1 //===- ValueList.cpp - Internal BitcodeReader implementation --------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/IR/Argument.h"
12 #include "llvm/IR/Constant.h"
13 #include "llvm/IR/Constants.h"
14 #include "llvm/IR/GlobalValue.h"
15 #include "llvm/IR/Instruction.h"
16 #include "llvm/IR/Type.h"
17 #include "llvm/IR/User.h"
18 #include "llvm/IR/Value.h"
19 #include "llvm/IR/ValueHandle.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/Support/ErrorHandling.h"
34 /// A class for maintaining the slot number definition
35 /// as a placeholder for the actual definition for forward constants defs.
36 class ConstantPlaceHolder
: public ConstantExpr
{
38 explicit ConstantPlaceHolder(Type
*Ty
, LLVMContext
&Context
)
39 : ConstantExpr(Ty
, Instruction::UserOp1
, &Op
<0>(), 1) {
40 Op
<0>() = UndefValue::get(Type::getInt32Ty(Context
));
43 ConstantPlaceHolder
&operator=(const ConstantPlaceHolder
&) = delete;
45 // allocate space for exactly one operand
46 void *operator new(size_t s
) { return User::operator new(s
, 1); }
48 /// Methods to support type inquiry through isa, cast, and dyn_cast.
49 static bool classof(const Value
*V
) {
50 return isa
<ConstantExpr
>(V
) &&
51 cast
<ConstantExpr
>(V
)->getOpcode() == Instruction::UserOp1
;
54 /// Provide fast operand accessors
55 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value
);
58 } // end anonymous namespace
60 // FIXME: can we inherit this from ConstantExpr?
62 struct OperandTraits
<ConstantPlaceHolder
>
63 : public FixedNumOperandTraits
<ConstantPlaceHolder
, 1> {};
64 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder
, Value
)
66 } // end namespace llvm
68 void BitcodeReaderValueList::assignValue(Value
*V
, unsigned Idx
, Type
*FullTy
) {
77 assert(FullTypes
[Idx
] == nullptr || FullTypes
[Idx
] == FullTy
);
78 FullTypes
[Idx
] = FullTy
;
80 WeakTrackingVH
&OldV
= ValuePtrs
[Idx
];
86 // Handle constants and non-constants (e.g. instrs) differently for
88 if (Constant
*PHC
= dyn_cast
<Constant
>(&*OldV
)) {
89 ResolveConstants
.push_back(std::make_pair(PHC
, Idx
));
92 // If there was a forward reference to this value, replace it.
93 Value
*PrevVal
= OldV
;
94 OldV
->replaceAllUsesWith(V
);
95 PrevVal
->deleteValue();
99 Constant
*BitcodeReaderValueList::getConstantFwdRef(unsigned Idx
, Type
*Ty
) {
103 if (Value
*V
= ValuePtrs
[Idx
]) {
104 if (Ty
!= V
->getType())
105 report_fatal_error("Type mismatch in constant table!");
106 return cast
<Constant
>(V
);
109 // Create and return a placeholder, which will later be RAUW'd.
110 Constant
*C
= new ConstantPlaceHolder(Ty
, Context
);
115 Value
*BitcodeReaderValueList::getValueFwdRef(unsigned Idx
, Type
*Ty
,
117 // Bail out for a clearly invalid value. This would make us call resize(0)
118 if (Idx
== std::numeric_limits
<unsigned>::max())
124 if (Value
*V
= ValuePtrs
[Idx
]) {
125 // If the types don't match, it's invalid.
126 if (Ty
&& Ty
!= V
->getType())
129 *FullTy
= FullTypes
[Idx
];
133 // No type specified, must be invalid reference.
137 // Create and return a placeholder, which will later be RAUW'd.
138 Value
*V
= new Argument(Ty
);
143 /// Once all constants are read, this method bulk resolves any forward
144 /// references. The idea behind this is that we sometimes get constants (such
145 /// as large arrays) which reference *many* forward ref constants. Replacing
146 /// each of these causes a lot of thrashing when building/reuniquing the
147 /// constant. Instead of doing this, we look at all the uses and rewrite all
148 /// the place holders at once for any constant that uses a placeholder.
149 void BitcodeReaderValueList::resolveConstantForwardRefs() {
150 // Sort the values by-pointer so that they are efficient to look up with a
152 llvm::sort(ResolveConstants
);
154 SmallVector
<Constant
*, 64> NewOps
;
156 while (!ResolveConstants
.empty()) {
157 Value
*RealVal
= operator[](ResolveConstants
.back().second
);
158 Constant
*Placeholder
= ResolveConstants
.back().first
;
159 ResolveConstants
.pop_back();
161 // Loop over all users of the placeholder, updating them to reference the
162 // new value. If they reference more than one placeholder, update them all
164 while (!Placeholder
->use_empty()) {
165 auto UI
= Placeholder
->user_begin();
168 // If the using object isn't uniqued, just update the operands. This
169 // handles instructions and initializers for global variables.
170 if (!isa
<Constant
>(U
) || isa
<GlobalValue
>(U
)) {
171 UI
.getUse().set(RealVal
);
175 // Otherwise, we have a constant that uses the placeholder. Replace that
176 // constant with a new constant that has *all* placeholder uses updated.
177 Constant
*UserC
= cast
<Constant
>(U
);
178 for (User::op_iterator I
= UserC
->op_begin(), E
= UserC
->op_end(); I
!= E
;
181 if (!isa
<ConstantPlaceHolder
>(*I
)) {
182 // Not a placeholder reference.
184 } else if (*I
== Placeholder
) {
185 // Common case is that it just references this one placeholder.
188 // Otherwise, look up the placeholder in ResolveConstants.
189 ResolveConstantsTy::iterator It
= llvm::lower_bound(
191 std::pair
<Constant
*, unsigned>(cast
<Constant
>(*I
), 0));
192 assert(It
!= ResolveConstants
.end() && It
->first
== *I
);
193 NewOp
= operator[](It
->second
);
196 NewOps
.push_back(cast
<Constant
>(NewOp
));
199 // Make the new constant.
201 if (ConstantArray
*UserCA
= dyn_cast
<ConstantArray
>(UserC
)) {
202 NewC
= ConstantArray::get(UserCA
->getType(), NewOps
);
203 } else if (ConstantStruct
*UserCS
= dyn_cast
<ConstantStruct
>(UserC
)) {
204 NewC
= ConstantStruct::get(UserCS
->getType(), NewOps
);
205 } else if (isa
<ConstantVector
>(UserC
)) {
206 NewC
= ConstantVector::get(NewOps
);
208 assert(isa
<ConstantExpr
>(UserC
) && "Must be a ConstantExpr.");
209 NewC
= cast
<ConstantExpr
>(UserC
)->getWithOperands(NewOps
);
212 UserC
->replaceAllUsesWith(NewC
);
213 UserC
->destroyConstant();
217 // Update all ValueHandles, they should be the only users at this point.
218 Placeholder
->replaceAllUsesWith(RealVal
);
219 Placeholder
->deleteValue();