1292915Sdim//===- SplitModule.cpp - Split a module into partitions -------------------===// 2292915Sdim// 3292915Sdim// The LLVM Compiler Infrastructure 4292915Sdim// 5292915Sdim// This file is distributed under the University of Illinois Open Source 6292915Sdim// License. See LICENSE.TXT for details. 7292915Sdim// 8292915Sdim//===----------------------------------------------------------------------===// 9292915Sdim// 10292915Sdim// This file defines the function llvm::SplitModule, which splits a module 11292915Sdim// into multiple linkable partitions. It can be used to implement parallel code 12292915Sdim// generation for link-time optimization. 13292915Sdim// 14292915Sdim//===----------------------------------------------------------------------===// 15292915Sdim 16292915Sdim#include "llvm/Transforms/Utils/SplitModule.h" 17292915Sdim#include "llvm/ADT/Hashing.h" 18292915Sdim#include "llvm/IR/Function.h" 19292915Sdim#include "llvm/IR/GlobalAlias.h" 20292915Sdim#include "llvm/IR/GlobalObject.h" 21292915Sdim#include "llvm/IR/GlobalValue.h" 22292915Sdim#include "llvm/IR/Module.h" 23292915Sdim#include "llvm/Support/MD5.h" 24292915Sdim#include "llvm/Support/raw_ostream.h" 25292915Sdim#include "llvm/Transforms/Utils/Cloning.h" 26292915Sdim 27292915Sdimusing namespace llvm; 28292915Sdim 29292915Sdimstatic void externalize(GlobalValue *GV) { 30292915Sdim if (GV->hasLocalLinkage()) { 31292915Sdim GV->setLinkage(GlobalValue::ExternalLinkage); 32292915Sdim GV->setVisibility(GlobalValue::HiddenVisibility); 33292915Sdim } 34292915Sdim 35292915Sdim // Unnamed entities must be named consistently between modules. setName will 36292915Sdim // give a distinct name to each such entity. 37292915Sdim if (!GV->hasName()) 38292915Sdim GV->setName("__llvmsplit_unnamed"); 39292915Sdim} 40292915Sdim 41292915Sdim// Returns whether GV should be in partition (0-based) I of N. 42292915Sdimstatic bool isInPartition(const GlobalValue *GV, unsigned I, unsigned N) { 43292915Sdim if (auto GA = dyn_cast<GlobalAlias>(GV)) 44292915Sdim if (const GlobalObject *Base = GA->getBaseObject()) 45292915Sdim GV = Base; 46292915Sdim 47292915Sdim StringRef Name; 48292915Sdim if (const Comdat *C = GV->getComdat()) 49292915Sdim Name = C->getName(); 50292915Sdim else 51292915Sdim Name = GV->getName(); 52292915Sdim 53292915Sdim // Partition by MD5 hash. We only need a few bits for evenness as the number 54292915Sdim // of partitions will generally be in the 1-2 figure range; the low 16 bits 55292915Sdim // are enough. 56292915Sdim MD5 H; 57292915Sdim MD5::MD5Result R; 58292915Sdim H.update(Name); 59292915Sdim H.final(R); 60292915Sdim return (R[0] | (R[1] << 8)) % N == I; 61292915Sdim} 62292915Sdim 63292915Sdimvoid llvm::SplitModule( 64292915Sdim std::unique_ptr<Module> M, unsigned N, 65292915Sdim std::function<void(std::unique_ptr<Module> MPart)> ModuleCallback) { 66292915Sdim for (Function &F : *M) 67292915Sdim externalize(&F); 68292915Sdim for (GlobalVariable &GV : M->globals()) 69292915Sdim externalize(&GV); 70292915Sdim for (GlobalAlias &GA : M->aliases()) 71292915Sdim externalize(&GA); 72292915Sdim 73292915Sdim // FIXME: We should be able to reuse M as the last partition instead of 74292915Sdim // cloning it. 75292915Sdim for (unsigned I = 0; I != N; ++I) { 76292915Sdim ValueToValueMapTy VMap; 77292915Sdim std::unique_ptr<Module> MPart( 78292915Sdim CloneModule(M.get(), VMap, [=](const GlobalValue *GV) { 79292915Sdim return isInPartition(GV, I, N); 80292915Sdim })); 81292915Sdim if (I != 0) 82292915Sdim MPart->setModuleInlineAsm(""); 83292915Sdim ModuleCallback(std::move(MPart)); 84292915Sdim } 85292915Sdim} 86