10b57cec5SDimitry Andric //===- ValueList.cpp - Internal BitcodeReader implementation --------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "ValueList.h"
100b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
110b57cec5SDimitry Andric #include "llvm/IR/Argument.h"
120b57cec5SDimitry Andric #include "llvm/IR/Constant.h"
130b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
140b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h"
150b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
160b57cec5SDimitry Andric #include "llvm/IR/Type.h"
170b57cec5SDimitry Andric #include "llvm/IR/User.h"
180b57cec5SDimitry Andric #include "llvm/IR/Value.h"
190b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
210b57cec5SDimitry Andric #include <algorithm>
220b57cec5SDimitry Andric #include <cstddef>
230b57cec5SDimitry Andric #include <limits>
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric using namespace llvm;
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric namespace llvm {
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric namespace {
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric /// A class for maintaining the slot number definition
320b57cec5SDimitry Andric /// as a placeholder for the actual definition for forward constants defs.
330b57cec5SDimitry Andric class ConstantPlaceHolder : public ConstantExpr {
340b57cec5SDimitry Andric public:
ConstantPlaceHolder(Type * Ty,LLVMContext & Context)350b57cec5SDimitry Andric   explicit ConstantPlaceHolder(Type *Ty, LLVMContext &Context)
360b57cec5SDimitry Andric       : ConstantExpr(Ty, Instruction::UserOp1, &Op<0>(), 1) {
370b57cec5SDimitry Andric     Op<0>() = UndefValue::get(Type::getInt32Ty(Context));
380b57cec5SDimitry Andric   }
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric   ConstantPlaceHolder &operator=(const ConstantPlaceHolder &) = delete;
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   // allocate space for exactly one operand
operator new(size_t s)430b57cec5SDimitry Andric   void *operator new(size_t s) { return User::operator new(s, 1); }
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   /// Methods to support type inquiry through isa, cast, and dyn_cast.
classof(const Value * V)460b57cec5SDimitry Andric   static bool classof(const Value *V) {
470b57cec5SDimitry Andric     return isa<ConstantExpr>(V) &&
480b57cec5SDimitry Andric            cast<ConstantExpr>(V)->getOpcode() == Instruction::UserOp1;
490b57cec5SDimitry Andric   }
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric   /// Provide fast operand accessors
520b57cec5SDimitry Andric   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
530b57cec5SDimitry Andric };
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric } // end anonymous namespace
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric // FIXME: can we inherit this from ConstantExpr?
580b57cec5SDimitry Andric template <>
590b57cec5SDimitry Andric struct OperandTraits<ConstantPlaceHolder>
600b57cec5SDimitry Andric     : public FixedNumOperandTraits<ConstantPlaceHolder, 1> {};
610b57cec5SDimitry Andric DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric } // end namespace llvm
640b57cec5SDimitry Andric 
assignValue(Value * V,unsigned Idx)65*5f7ddb14SDimitry Andric void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
660b57cec5SDimitry Andric   if (Idx == size()) {
67*5f7ddb14SDimitry Andric     push_back(V);
680b57cec5SDimitry Andric     return;
690b57cec5SDimitry Andric   }
700b57cec5SDimitry Andric 
710b57cec5SDimitry Andric   if (Idx >= size())
720b57cec5SDimitry Andric     resize(Idx + 1);
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   WeakTrackingVH &OldV = ValuePtrs[Idx];
750b57cec5SDimitry Andric   if (!OldV) {
760b57cec5SDimitry Andric     OldV = V;
770b57cec5SDimitry Andric     return;
780b57cec5SDimitry Andric   }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   // Handle constants and non-constants (e.g. instrs) differently for
810b57cec5SDimitry Andric   // efficiency.
820b57cec5SDimitry Andric   if (Constant *PHC = dyn_cast<Constant>(&*OldV)) {
830b57cec5SDimitry Andric     ResolveConstants.push_back(std::make_pair(PHC, Idx));
840b57cec5SDimitry Andric     OldV = V;
850b57cec5SDimitry Andric   } else {
860b57cec5SDimitry Andric     // If there was a forward reference to this value, replace it.
870b57cec5SDimitry Andric     Value *PrevVal = OldV;
880b57cec5SDimitry Andric     OldV->replaceAllUsesWith(V);
890b57cec5SDimitry Andric     PrevVal->deleteValue();
900b57cec5SDimitry Andric   }
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
getConstantFwdRef(unsigned Idx,Type * Ty)930b57cec5SDimitry Andric Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, Type *Ty) {
940b57cec5SDimitry Andric   // Bail out for a clearly invalid value.
950b57cec5SDimitry Andric   if (Idx >= RefsUpperBound)
960b57cec5SDimitry Andric     return nullptr;
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   if (Idx >= size())
990b57cec5SDimitry Andric     resize(Idx + 1);
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   if (Value *V = ValuePtrs[Idx]) {
1020b57cec5SDimitry Andric     if (Ty != V->getType())
1030b57cec5SDimitry Andric       report_fatal_error("Type mismatch in constant table!");
1040b57cec5SDimitry Andric     return cast<Constant>(V);
1050b57cec5SDimitry Andric   }
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric   // Create and return a placeholder, which will later be RAUW'd.
1080b57cec5SDimitry Andric   Constant *C = new ConstantPlaceHolder(Ty, Context);
1090b57cec5SDimitry Andric   ValuePtrs[Idx] = C;
1100b57cec5SDimitry Andric   return C;
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
getValueFwdRef(unsigned Idx,Type * Ty)113*5f7ddb14SDimitry Andric Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) {
1140b57cec5SDimitry Andric   // Bail out for a clearly invalid value.
1150b57cec5SDimitry Andric   if (Idx >= RefsUpperBound)
1160b57cec5SDimitry Andric     return nullptr;
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric   if (Idx >= size())
1190b57cec5SDimitry Andric     resize(Idx + 1);
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric   if (Value *V = ValuePtrs[Idx]) {
1220b57cec5SDimitry Andric     // If the types don't match, it's invalid.
1230b57cec5SDimitry Andric     if (Ty && Ty != V->getType())
1240b57cec5SDimitry Andric       return nullptr;
1250b57cec5SDimitry Andric     return V;
1260b57cec5SDimitry Andric   }
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   // No type specified, must be invalid reference.
1290b57cec5SDimitry Andric   if (!Ty)
1300b57cec5SDimitry Andric     return nullptr;
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric   // Create and return a placeholder, which will later be RAUW'd.
1330b57cec5SDimitry Andric   Value *V = new Argument(Ty);
1340b57cec5SDimitry Andric   ValuePtrs[Idx] = V;
1350b57cec5SDimitry Andric   return V;
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric /// Once all constants are read, this method bulk resolves any forward
1390b57cec5SDimitry Andric /// references.  The idea behind this is that we sometimes get constants (such
1400b57cec5SDimitry Andric /// as large arrays) which reference *many* forward ref constants.  Replacing
1410b57cec5SDimitry Andric /// each of these causes a lot of thrashing when building/reuniquing the
1420b57cec5SDimitry Andric /// constant.  Instead of doing this, we look at all the uses and rewrite all
1430b57cec5SDimitry Andric /// the place holders at once for any constant that uses a placeholder.
resolveConstantForwardRefs()1440b57cec5SDimitry Andric void BitcodeReaderValueList::resolveConstantForwardRefs() {
1450b57cec5SDimitry Andric   // Sort the values by-pointer so that they are efficient to look up with a
1460b57cec5SDimitry Andric   // binary search.
1470b57cec5SDimitry Andric   llvm::sort(ResolveConstants);
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric   SmallVector<Constant *, 64> NewOps;
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   while (!ResolveConstants.empty()) {
1520b57cec5SDimitry Andric     Value *RealVal = operator[](ResolveConstants.back().second);
1530b57cec5SDimitry Andric     Constant *Placeholder = ResolveConstants.back().first;
1540b57cec5SDimitry Andric     ResolveConstants.pop_back();
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric     // Loop over all users of the placeholder, updating them to reference the
1570b57cec5SDimitry Andric     // new value.  If they reference more than one placeholder, update them all
1580b57cec5SDimitry Andric     // at once.
1590b57cec5SDimitry Andric     while (!Placeholder->use_empty()) {
1600b57cec5SDimitry Andric       auto UI = Placeholder->user_begin();
1610b57cec5SDimitry Andric       User *U = *UI;
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric       // If the using object isn't uniqued, just update the operands.  This
1640b57cec5SDimitry Andric       // handles instructions and initializers for global variables.
1650b57cec5SDimitry Andric       if (!isa<Constant>(U) || isa<GlobalValue>(U)) {
1660b57cec5SDimitry Andric         UI.getUse().set(RealVal);
1670b57cec5SDimitry Andric         continue;
1680b57cec5SDimitry Andric       }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric       // Otherwise, we have a constant that uses the placeholder.  Replace that
1710b57cec5SDimitry Andric       // constant with a new constant that has *all* placeholder uses updated.
1720b57cec5SDimitry Andric       Constant *UserC = cast<Constant>(U);
1730b57cec5SDimitry Andric       for (User::op_iterator I = UserC->op_begin(), E = UserC->op_end(); I != E;
1740b57cec5SDimitry Andric            ++I) {
1750b57cec5SDimitry Andric         Value *NewOp;
1760b57cec5SDimitry Andric         if (!isa<ConstantPlaceHolder>(*I)) {
1770b57cec5SDimitry Andric           // Not a placeholder reference.
1780b57cec5SDimitry Andric           NewOp = *I;
1790b57cec5SDimitry Andric         } else if (*I == Placeholder) {
1800b57cec5SDimitry Andric           // Common case is that it just references this one placeholder.
1810b57cec5SDimitry Andric           NewOp = RealVal;
1820b57cec5SDimitry Andric         } else {
1830b57cec5SDimitry Andric           // Otherwise, look up the placeholder in ResolveConstants.
1840b57cec5SDimitry Andric           ResolveConstantsTy::iterator It = llvm::lower_bound(
1850b57cec5SDimitry Andric               ResolveConstants,
1860b57cec5SDimitry Andric               std::pair<Constant *, unsigned>(cast<Constant>(*I), 0));
1870b57cec5SDimitry Andric           assert(It != ResolveConstants.end() && It->first == *I);
1880b57cec5SDimitry Andric           NewOp = operator[](It->second);
1890b57cec5SDimitry Andric         }
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric         NewOps.push_back(cast<Constant>(NewOp));
1920b57cec5SDimitry Andric       }
1930b57cec5SDimitry Andric 
1940b57cec5SDimitry Andric       // Make the new constant.
1950b57cec5SDimitry Andric       Constant *NewC;
1960b57cec5SDimitry Andric       if (ConstantArray *UserCA = dyn_cast<ConstantArray>(UserC)) {
1970b57cec5SDimitry Andric         NewC = ConstantArray::get(UserCA->getType(), NewOps);
1980b57cec5SDimitry Andric       } else if (ConstantStruct *UserCS = dyn_cast<ConstantStruct>(UserC)) {
1990b57cec5SDimitry Andric         NewC = ConstantStruct::get(UserCS->getType(), NewOps);
2000b57cec5SDimitry Andric       } else if (isa<ConstantVector>(UserC)) {
2010b57cec5SDimitry Andric         NewC = ConstantVector::get(NewOps);
2020b57cec5SDimitry Andric       } else {
2030b57cec5SDimitry Andric         assert(isa<ConstantExpr>(UserC) && "Must be a ConstantExpr.");
2040b57cec5SDimitry Andric         NewC = cast<ConstantExpr>(UserC)->getWithOperands(NewOps);
2050b57cec5SDimitry Andric       }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric       UserC->replaceAllUsesWith(NewC);
2080b57cec5SDimitry Andric       UserC->destroyConstant();
2090b57cec5SDimitry Andric       NewOps.clear();
2100b57cec5SDimitry Andric     }
2110b57cec5SDimitry Andric 
2120b57cec5SDimitry Andric     // Update all ValueHandles, they should be the only users at this point.
2130b57cec5SDimitry Andric     Placeholder->replaceAllUsesWith(RealVal);
2145ffd83dbSDimitry Andric     delete cast<ConstantPlaceHolder>(Placeholder);
2150b57cec5SDimitry Andric   }
2160b57cec5SDimitry Andric }
217