// @LOCALMOD-BEGIN static void wrapSymbol(Module *M, const char *sym) { std::string wrapSymName("__wrap_"); wrapSymName += sym; std::string realSymName("__real_"); realSymName += sym; Constant *SymGV = M->getNamedValue(sym); // Replace uses of "sym" with "__wrap_sym". if (SymGV) { Constant *WrapGV = M->getNamedValue(wrapSymName); if (!WrapGV) WrapGV = M->getOrInsertGlobal(wrapSymName, SymGV->getType()); SymGV->replaceAllUsesWith( ConstantExpr::getBitCast(WrapGV, SymGV->getType())); } // Replace uses of "__real_sym" with "sym". if (Constant *RealGV = M->getNamedValue(realSymName)) { if (!SymGV) SymGV = M->getOrInsertGlobal(sym, RealGV->getType()); RealGV->replaceAllUsesWith( ConstantExpr::getBitCast(SymGV, RealGV->getType())); } }
/// Once all constants are read, this method bulk resolves any forward /// references. The idea behind this is that we sometimes get constants (such /// as large arrays) which reference *many* forward ref constants. Replacing /// each of these causes a lot of thrashing when building/reuniquing the /// constant. Instead of doing this, we look at all the uses and rewrite all /// the place holders at once for any constant that uses a placeholder. void BitcodeReaderValueList::resolveConstantForwardRefs() { // Sort the values by-pointer so that they are efficient to look up with a // binary search. llvm::sort(ResolveConstants); SmallVector<Constant *, 64> NewOps; while (!ResolveConstants.empty()) { Value *RealVal = operator[](ResolveConstants.back().second); Constant *Placeholder = ResolveConstants.back().first; ResolveConstants.pop_back(); // Loop over all users of the placeholder, updating them to reference the // new value. If they reference more than one placeholder, update them all // at once. while (!Placeholder->use_empty()) { auto UI = Placeholder->user_begin(); User *U = *UI; // If the using object isn't uniqued, just update the operands. This // handles instructions and initializers for global variables. if (!isa<Constant>(U) || isa<GlobalValue>(U)) { UI.getUse().set(RealVal); continue; } // Otherwise, we have a constant that uses the placeholder. Replace that // constant with a new constant that has *all* placeholder uses updated. Constant *UserC = cast<Constant>(U); for (User::op_iterator I = UserC->op_begin(), E = UserC->op_end(); I != E; ++I) { Value *NewOp; if (!isa<ConstantPlaceHolder>(*I)) { // Not a placeholder reference. NewOp = *I; } else if (*I == Placeholder) { // Common case is that it just references this one placeholder. NewOp = RealVal; } else { // Otherwise, look up the placeholder in ResolveConstants. ResolveConstantsTy::iterator It = llvm::lower_bound( ResolveConstants, std::pair<Constant *, unsigned>(cast<Constant>(*I), 0)); assert(It != ResolveConstants.end() && It->first == *I); NewOp = operator[](It->second); } NewOps.push_back(cast<Constant>(NewOp)); } // Make the new constant. Constant *NewC; if (ConstantArray *UserCA = dyn_cast<ConstantArray>(UserC)) { NewC = ConstantArray::get(UserCA->getType(), NewOps); } else if (ConstantStruct *UserCS = dyn_cast<ConstantStruct>(UserC)) { NewC = ConstantStruct::get(UserCS->getType(), NewOps); } else if (isa<ConstantVector>(UserC)) { NewC = ConstantVector::get(NewOps); } else { assert(isa<ConstantExpr>(UserC) && "Must be a ConstantExpr."); NewC = cast<ConstantExpr>(UserC)->getWithOperands(NewOps); } UserC->replaceAllUsesWith(NewC); UserC->destroyConstant(); NewOps.clear(); } // Update all ValueHandles, they should be the only users at this point. Placeholder->replaceAllUsesWith(RealVal); Placeholder->deleteValue(); } }