ValueMapper.cpp revision 3cf5db73c7382c7236256779513fdeb1075f2f16
1//===- ValueMapper.cpp - Interface shared by lib/Transforms/Utils ---------===//
2//
3// This file defines the MapValue function, which is shared by various parts of
4// the lib/Transforms/Utils library.
5//
6//===----------------------------------------------------------------------===//
7
8#include "ValueMapper.h"
9#include "llvm/Constants.h"
10#include "llvm/Instruction.h"
11
12Value *MapValue(const Value *V, std::map<const Value*, Value*> &VM) {
13  Value *&VMSlot = VM[V];
14  if (VMSlot) return VMSlot;      // Does it exist in the map yet?
15
16  if (Constant *C = (Constant*)dyn_cast<Constant>(V)) {
17    if (isa<ConstantIntegral>(C) || isa<ConstantFP>(C) ||
18        isa<ConstantPointerNull>(C))
19      return VMSlot = C;           // Primitive constants map directly
20    else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) {
21      GlobalValue *MV = cast<GlobalValue>(MapValue((Value*)CPR->getValue(),VM));
22      return VMSlot = ConstantPointerRef::get(MV);
23    } else if (ConstantArray *CA = dyn_cast<ConstantArray>(C)) {
24      const std::vector<Use> &Vals = CA->getValues();
25      for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
26        Value *MV = MapValue(Vals[i], VM);
27        if (MV != Vals[i]) {
28          // This array must contain a reference to a global, make a new array
29          // and return it.
30          //
31          std::vector<Constant*> Values;
32          Values.reserve(Vals.size());
33          for (unsigned j = 0; j != i; ++j)
34            Values.push_back(cast<Constant>(Vals[j]));
35          Values.push_back(cast<Constant>(MV));
36          for (++i; i != e; ++i)
37            Values.push_back(cast<Constant>(MapValue(Vals[i], VM)));
38          return VMSlot = ConstantArray::get(CA->getType(), Values);
39        }
40      }
41      return VMSlot = C;
42
43    } else if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
44      const std::vector<Use> &Vals = CS->getValues();
45      for (unsigned i = 0, e = Vals.size(); i != e; ++i) {
46        Value *MV = MapValue(Vals[i], VM);
47        if (MV != Vals[i]) {
48          // This struct must contain a reference to a global, make a new struct
49          // and return it.
50          //
51          std::vector<Constant*> Values;
52          Values.reserve(Vals.size());
53          for (unsigned j = 0; j != i; ++j)
54            Values.push_back(cast<Constant>(Vals[j]));
55          Values.push_back(cast<Constant>(MV));
56          for (++i; i != e; ++i)
57            Values.push_back(cast<Constant>(MapValue(Vals[i], VM)));
58          return VMSlot = ConstantStruct::get(CS->getType(), Values);
59        }
60      }
61      return VMSlot = C;
62
63    } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
64      if (CE->getOpcode() == Instruction::Cast) {
65        Constant *MV = cast<Constant>(MapValue(CE->getOperand(0), VM));
66        return VMSlot = ConstantExpr::getCast(MV, CE->getType());
67      } else if (CE->getOpcode() == Instruction::GetElementPtr) {
68        std::vector<Constant*> Idx;
69        Constant *MV = cast<Constant>(MapValue(CE->getOperand(0), VM));
70        for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
71          Idx.push_back(cast<Constant>(MapValue(CE->getOperand(i), VM)));
72        return VMSlot = ConstantExpr::getGetElementPtr(MV, Idx);
73      } else {
74        assert(CE->getNumOperands() == 2 && "Must be binary operator?");
75        Constant *MV1 = cast<Constant>(MapValue(CE->getOperand(0), VM));
76        Constant *MV2 = cast<Constant>(MapValue(CE->getOperand(1), VM));
77        return VMSlot = ConstantExpr::get(CE->getOpcode(), MV1, MV2);
78      }
79
80    } else {
81      assert(0 && "Unknown type of constant!");
82    }
83  }
84
85  V->dump();
86  assert(0 && "Unknown value type: why didn't it get resolved?!");
87  return 0;
88}
89
90