bool RegisterGlobals::runOnModule(Module &M) { TD = &getAnalysis<TargetData>(); VoidTy = Type::getVoidTy(M.getContext()); VoidPtrTy = Type::getInt8PtrTy(M.getContext()); SizeTy = IntegerType::getInt64Ty(M.getContext()); // Create the function prototype M.getOrInsertFunction("__pool_register_global", VoidTy, VoidPtrTy, SizeTy, NULL); RegisterGlobalPoolFunction = M.getFunction("__pool_register_global"); // Create the function that will contain the registration calls createRegistrationFunction(M); Module::global_iterator GI = M.global_begin(), GE = M.global_end(); for ( ; GI != GE; ++GI) { GlobalVariable *GV = GI; // Skip globals without a size if (!GV->getType()->getElementType()->isSized()) continue; // Optionally avoid registering globals with uncertain size. if (!RegUncertain) { // Linking can change the size of declarations if (GV->isDeclaration()) continue; // Linking can't change the size of defined globals with eternal linkage. // Linking can't change the size of globals with local linkage. if (!GV->hasExternalLinkage() && !GV->hasLocalLinkage()) continue; } // Thread-local globals would have to be registered for each thread. // FIXME: add support for thread-local globals if (GV->isThreadLocal()) continue; registerGlobal(GV); } return true; }