12ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel//===-- ModuleUtils.cpp - Functions to manipulate Modules -----------------===// 22ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel// 32ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel// The LLVM Compiler Infrastructure 42ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel// 52ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel// This file is distributed under the University of Illinois Open Source 62ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel// License. See LICENSE.TXT for details. 72ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel// 82ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel//===----------------------------------------------------------------------===// 92ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel// 102ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel// This family of functions perform manipulations on Modules. 112ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel// 122ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel//===----------------------------------------------------------------------===// 132ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel 142ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel#include "llvm/Transforms/Utils/ModuleUtils.h" 154ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola#include "llvm/ADT/SmallPtrSet.h" 160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h" 190b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 20a2a2d1fddd0c2de82fb90be8fb1e0ec2ed6c44acKostya Serebryany 212ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patelusing namespace llvm; 222ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel 237bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryanystatic void appendToGlobalArray(const char *Array, 247bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany Module &M, Function *F, int Priority) { 252ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel IRBuilder<> IRB(M.getContext()); 262ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel FunctionType *FnTy = FunctionType::get(IRB.getVoidTy(), false); 272ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel StructType *Ty = StructType::get( 282ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel IRB.getInt32Ty(), PointerType::getUnqual(FnTy), NULL); 292ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel 302ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel Constant *RuntimeCtorInit = ConstantStruct::get( 312ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel Ty, IRB.getInt32(Priority), F, NULL); 322ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel 332ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel // Get the current set of static global constructors and add the new ctor 342ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel // to the list. 352ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel SmallVector<Constant *, 16> CurrentCtors; 367bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany if (GlobalVariable * GVCtor = M.getNamedGlobal(Array)) { 372ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel if (Constant *Init = GVCtor->getInitializer()) { 382ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel unsigned n = Init->getNumOperands(); 392ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel CurrentCtors.reserve(n + 1); 402ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel for (unsigned i = 0; i != n; ++i) 412ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel CurrentCtors.push_back(cast<Constant>(Init->getOperand(i))); 422ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel } 432ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel GVCtor->eraseFromParent(); 442ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel } 452ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel 462ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel CurrentCtors.push_back(RuntimeCtorInit); 472ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel 482ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel // Create a new initializer. 492ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel ArrayType *AT = ArrayType::get(RuntimeCtorInit->getType(), 502ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel CurrentCtors.size()); 512ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel Constant *NewInit = ConstantArray::get(AT, CurrentCtors); 522ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel 532ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel // Create the new global variable and replace all uses of 542ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel // the old global variable with the new one. 552ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel (void)new GlobalVariable(M, NewInit->getType(), false, 567bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany GlobalValue::AppendingLinkage, NewInit, Array); 577bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany} 587bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany 597bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryanyvoid llvm::appendToGlobalCtors(Module &M, Function *F, int Priority) { 607bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany appendToGlobalArray("llvm.global_ctors", M, F, Priority); 617bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany} 627bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany 637bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryanyvoid llvm::appendToGlobalDtors(Module &M, Function *F, int Priority) { 647bcfc9950bac0f411f9671e8d6ce483bd219727eKostya Serebryany appendToGlobalArray("llvm.global_dtors", M, F, Priority); 652ad3f93b5f1d6e22f682efd6fd10f7f3ed9fa992Devang Patel} 664ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola 674ef7eafa3f823443d1b8921f6020d946612281dbRafael EspindolaGlobalVariable * 684ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindolallvm::collectUsedGlobalVariables(Module &M, SmallPtrSet<GlobalValue *, 8> &Set, 694ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola bool CompilerUsed) { 704ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used"; 714ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola GlobalVariable *GV = M.getGlobalVariable(Name); 724ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola if (!GV || !GV->hasInitializer()) 734ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola return GV; 744ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola 754ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola const ConstantArray *Init = cast<ConstantArray>(GV->getInitializer()); 764ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola for (unsigned I = 0, E = Init->getNumOperands(); I != E; ++I) { 774ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola Value *Op = Init->getOperand(I); 784ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola GlobalValue *G = cast<GlobalValue>(Op->stripPointerCastsNoFollowAliases()); 794ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola Set.insert(G); 804ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola } 814ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola return GV; 824ef7eafa3f823443d1b8921f6020d946612281dbRafael Espindola} 83