1*0b57cec5SDimitry Andric //===- ExtractFunction.cpp - Extract a function from Program --------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This file implements several methods that are used to extract functions,
10*0b57cec5SDimitry Andric // loops, or portions of a module from the rest of the module.
11*0b57cec5SDimitry Andric //
12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
13*0b57cec5SDimitry Andric 
14*0b57cec5SDimitry Andric #include "BugDriver.h"
15*0b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
16*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
17*0b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
18*0b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
19*0b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
20*0b57cec5SDimitry Andric #include "llvm/IR/Module.h"
21*0b57cec5SDimitry Andric #include "llvm/IR/Verifier.h"
22*0b57cec5SDimitry Andric #include "llvm/Pass.h"
23*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
24*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
25*0b57cec5SDimitry Andric #include "llvm/Support/FileUtilities.h"
26*0b57cec5SDimitry Andric #include "llvm/Support/Path.h"
27*0b57cec5SDimitry Andric #include "llvm/Support/Signals.h"
28*0b57cec5SDimitry Andric #include "llvm/Support/ToolOutputFile.h"
29*0b57cec5SDimitry Andric #include "llvm/Transforms/IPO.h"
30*0b57cec5SDimitry Andric #include "llvm/Transforms/Scalar.h"
31*0b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h"
32*0b57cec5SDimitry Andric #include "llvm/Transforms/Utils/CodeExtractor.h"
33*0b57cec5SDimitry Andric #include <set>
34*0b57cec5SDimitry Andric using namespace llvm;
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric #define DEBUG_TYPE "bugpoint"
37*0b57cec5SDimitry Andric 
38*0b57cec5SDimitry Andric namespace llvm {
39*0b57cec5SDimitry Andric bool DisableSimplifyCFG = false;
40*0b57cec5SDimitry Andric extern cl::opt<std::string> OutputPrefix;
41*0b57cec5SDimitry Andric } // End llvm namespace
42*0b57cec5SDimitry Andric 
43*0b57cec5SDimitry Andric namespace {
44*0b57cec5SDimitry Andric cl::opt<bool> NoDCE("disable-dce",
45*0b57cec5SDimitry Andric                     cl::desc("Do not use the -dce pass to reduce testcases"));
46*0b57cec5SDimitry Andric cl::opt<bool, true>
47*0b57cec5SDimitry Andric     NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG),
48*0b57cec5SDimitry Andric            cl::desc("Do not use the -simplifycfg pass to reduce testcases"));
49*0b57cec5SDimitry Andric 
globalInitUsesExternalBA(GlobalVariable * GV)50*0b57cec5SDimitry Andric Function *globalInitUsesExternalBA(GlobalVariable *GV) {
51*0b57cec5SDimitry Andric   if (!GV->hasInitializer())
52*0b57cec5SDimitry Andric     return nullptr;
53*0b57cec5SDimitry Andric 
54*0b57cec5SDimitry Andric   Constant *I = GV->getInitializer();
55*0b57cec5SDimitry Andric 
56*0b57cec5SDimitry Andric   // walk the values used by the initializer
57*0b57cec5SDimitry Andric   // (and recurse into things like ConstantExpr)
58*0b57cec5SDimitry Andric   std::vector<Constant *> Todo;
59*0b57cec5SDimitry Andric   std::set<Constant *> Done;
60*0b57cec5SDimitry Andric   Todo.push_back(I);
61*0b57cec5SDimitry Andric 
62*0b57cec5SDimitry Andric   while (!Todo.empty()) {
63*0b57cec5SDimitry Andric     Constant *V = Todo.back();
64*0b57cec5SDimitry Andric     Todo.pop_back();
65*0b57cec5SDimitry Andric     Done.insert(V);
66*0b57cec5SDimitry Andric 
67*0b57cec5SDimitry Andric     if (BlockAddress *BA = dyn_cast<BlockAddress>(V)) {
68*0b57cec5SDimitry Andric       Function *F = BA->getFunction();
69*0b57cec5SDimitry Andric       if (F->isDeclaration())
70*0b57cec5SDimitry Andric         return F;
71*0b57cec5SDimitry Andric     }
72*0b57cec5SDimitry Andric 
73*0b57cec5SDimitry Andric     for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) {
74*0b57cec5SDimitry Andric       Constant *C = dyn_cast<Constant>(*i);
75*0b57cec5SDimitry Andric       if (C && !isa<GlobalValue>(C) && !Done.count(C))
76*0b57cec5SDimitry Andric         Todo.push_back(C);
77*0b57cec5SDimitry Andric     }
78*0b57cec5SDimitry Andric   }
79*0b57cec5SDimitry Andric   return nullptr;
80*0b57cec5SDimitry Andric }
81*0b57cec5SDimitry Andric } // end anonymous namespace
82*0b57cec5SDimitry Andric 
83*0b57cec5SDimitry Andric std::unique_ptr<Module>
deleteInstructionFromProgram(const Instruction * I,unsigned Simplification)84*0b57cec5SDimitry Andric BugDriver::deleteInstructionFromProgram(const Instruction *I,
85*0b57cec5SDimitry Andric                                         unsigned Simplification) {
86*0b57cec5SDimitry Andric   // FIXME, use vmap?
87*0b57cec5SDimitry Andric   std::unique_ptr<Module> Clone = CloneModule(*Program);
88*0b57cec5SDimitry Andric 
89*0b57cec5SDimitry Andric   const BasicBlock *PBB = I->getParent();
90*0b57cec5SDimitry Andric   const Function *PF = PBB->getParent();
91*0b57cec5SDimitry Andric 
92*0b57cec5SDimitry Andric   Module::iterator RFI = Clone->begin(); // Get iterator to corresponding fn
93*0b57cec5SDimitry Andric   std::advance(
94*0b57cec5SDimitry Andric       RFI, std::distance(PF->getParent()->begin(), Module::const_iterator(PF)));
95*0b57cec5SDimitry Andric 
96*0b57cec5SDimitry Andric   Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB
97*0b57cec5SDimitry Andric   std::advance(RBI, std::distance(PF->begin(), Function::const_iterator(PBB)));
98*0b57cec5SDimitry Andric 
99*0b57cec5SDimitry Andric   BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst
100*0b57cec5SDimitry Andric   std::advance(RI, std::distance(PBB->begin(), BasicBlock::const_iterator(I)));
101*0b57cec5SDimitry Andric   Instruction *TheInst = &*RI; // Got the corresponding instruction!
102*0b57cec5SDimitry Andric 
103*0b57cec5SDimitry Andric   // If this instruction produces a value, replace any users with null values
104*0b57cec5SDimitry Andric   if (!TheInst->getType()->isVoidTy())
105*0b57cec5SDimitry Andric     TheInst->replaceAllUsesWith(Constant::getNullValue(TheInst->getType()));
106*0b57cec5SDimitry Andric 
107*0b57cec5SDimitry Andric   // Remove the instruction from the program.
108bdd1243dSDimitry Andric   TheInst->eraseFromParent();
109*0b57cec5SDimitry Andric 
110*0b57cec5SDimitry Andric   // Spiff up the output a little bit.
111*0b57cec5SDimitry Andric   std::vector<std::string> Passes;
112*0b57cec5SDimitry Andric 
113*0b57cec5SDimitry Andric   /// Can we get rid of the -disable-* options?
114*0b57cec5SDimitry Andric   if (Simplification > 1 && !NoDCE)
115*0b57cec5SDimitry Andric     Passes.push_back("dce");
116*0b57cec5SDimitry Andric   if (Simplification && !DisableSimplifyCFG)
117*0b57cec5SDimitry Andric     Passes.push_back("simplifycfg"); // Delete dead control flow
118*0b57cec5SDimitry Andric 
119*0b57cec5SDimitry Andric   Passes.push_back("verify");
120*0b57cec5SDimitry Andric   std::unique_ptr<Module> New = runPassesOn(Clone.get(), Passes);
121*0b57cec5SDimitry Andric   if (!New) {
122*0b57cec5SDimitry Andric     errs() << "Instruction removal failed.  Sorry. :(  Please report a bug!\n";
123*0b57cec5SDimitry Andric     exit(1);
124*0b57cec5SDimitry Andric   }
125*0b57cec5SDimitry Andric   return New;
126*0b57cec5SDimitry Andric }
127*0b57cec5SDimitry Andric 
128*0b57cec5SDimitry Andric std::unique_ptr<Module>
performFinalCleanups(std::unique_ptr<Module> M,bool MayModifySemantics)129*0b57cec5SDimitry Andric BugDriver::performFinalCleanups(std::unique_ptr<Module> M,
130*0b57cec5SDimitry Andric                                 bool MayModifySemantics) {
131*0b57cec5SDimitry Andric   // Make all functions external, so GlobalDCE doesn't delete them...
132*0b57cec5SDimitry Andric   for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
133*0b57cec5SDimitry Andric     I->setLinkage(GlobalValue::ExternalLinkage);
134*0b57cec5SDimitry Andric 
135*0b57cec5SDimitry Andric   std::vector<std::string> CleanupPasses;
136*0b57cec5SDimitry Andric 
137*0b57cec5SDimitry Andric   if (MayModifySemantics)
138*0b57cec5SDimitry Andric     CleanupPasses.push_back("deadarghaX0r");
139*0b57cec5SDimitry Andric   else
140*0b57cec5SDimitry Andric     CleanupPasses.push_back("deadargelim");
141*0b57cec5SDimitry Andric 
142*0b57cec5SDimitry Andric   std::unique_ptr<Module> New = runPassesOn(M.get(), CleanupPasses);
143*0b57cec5SDimitry Andric   if (!New) {
144*0b57cec5SDimitry Andric     errs() << "Final cleanups failed.  Sorry. :(  Please report a bug!\n";
145*0b57cec5SDimitry Andric     return nullptr;
146*0b57cec5SDimitry Andric   }
147*0b57cec5SDimitry Andric   return New;
148*0b57cec5SDimitry Andric }
149*0b57cec5SDimitry Andric 
extractLoop(Module * M)150*0b57cec5SDimitry Andric std::unique_ptr<Module> BugDriver::extractLoop(Module *M) {
151*0b57cec5SDimitry Andric   std::vector<std::string> LoopExtractPasses;
152*0b57cec5SDimitry Andric   LoopExtractPasses.push_back("loop-extract-single");
153*0b57cec5SDimitry Andric 
154*0b57cec5SDimitry Andric   std::unique_ptr<Module> NewM = runPassesOn(M, LoopExtractPasses);
155*0b57cec5SDimitry Andric   if (!NewM) {
156*0b57cec5SDimitry Andric     outs() << "*** Loop extraction failed: ";
157*0b57cec5SDimitry Andric     EmitProgressBitcode(*M, "loopextraction", true);
158*0b57cec5SDimitry Andric     outs() << "*** Sorry. :(  Please report a bug!\n";
159*0b57cec5SDimitry Andric     return nullptr;
160*0b57cec5SDimitry Andric   }
161*0b57cec5SDimitry Andric 
162*0b57cec5SDimitry Andric   // Check to see if we created any new functions.  If not, no loops were
163*0b57cec5SDimitry Andric   // extracted and we should return null.  Limit the number of loops we extract
164*0b57cec5SDimitry Andric   // to avoid taking forever.
165*0b57cec5SDimitry Andric   static unsigned NumExtracted = 32;
166*0b57cec5SDimitry Andric   if (M->size() == NewM->size() || --NumExtracted == 0) {
167*0b57cec5SDimitry Andric     return nullptr;
168*0b57cec5SDimitry Andric   } else {
169*0b57cec5SDimitry Andric     assert(M->size() < NewM->size() && "Loop extract removed functions?");
170*0b57cec5SDimitry Andric     Module::iterator MI = NewM->begin();
171*0b57cec5SDimitry Andric     for (unsigned i = 0, e = M->size(); i != e; ++i)
172*0b57cec5SDimitry Andric       ++MI;
173*0b57cec5SDimitry Andric   }
174*0b57cec5SDimitry Andric 
175*0b57cec5SDimitry Andric   return NewM;
176*0b57cec5SDimitry Andric }
177*0b57cec5SDimitry Andric 
eliminateAliases(GlobalValue * GV)178*0b57cec5SDimitry Andric static void eliminateAliases(GlobalValue *GV) {
179*0b57cec5SDimitry Andric   // First, check whether a GlobalAlias references this definition.
180*0b57cec5SDimitry Andric   // GlobalAlias MAY NOT reference declarations.
181*0b57cec5SDimitry Andric   for (;;) {
182*0b57cec5SDimitry Andric     // 1. Find aliases
183*0b57cec5SDimitry Andric     SmallVector<GlobalAlias *, 1> aliases;
184*0b57cec5SDimitry Andric     Module *M = GV->getParent();
185*0b57cec5SDimitry Andric     for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end();
186*0b57cec5SDimitry Andric          I != E; ++I)
187*0b57cec5SDimitry Andric       if (I->getAliasee()->stripPointerCasts() == GV)
188*0b57cec5SDimitry Andric         aliases.push_back(&*I);
189*0b57cec5SDimitry Andric     if (aliases.empty())
190*0b57cec5SDimitry Andric       break;
191*0b57cec5SDimitry Andric     // 2. Resolve aliases
192*0b57cec5SDimitry Andric     for (unsigned i = 0, e = aliases.size(); i < e; ++i) {
193*0b57cec5SDimitry Andric       aliases[i]->replaceAllUsesWith(aliases[i]->getAliasee());
194*0b57cec5SDimitry Andric       aliases[i]->eraseFromParent();
195*0b57cec5SDimitry Andric     }
196*0b57cec5SDimitry Andric     // 3. Repeat until no more aliases found; there might
197*0b57cec5SDimitry Andric     // be an alias to an alias...
198*0b57cec5SDimitry Andric   }
199*0b57cec5SDimitry Andric }
200*0b57cec5SDimitry Andric 
201*0b57cec5SDimitry Andric //
202*0b57cec5SDimitry Andric // DeleteGlobalInitializer - "Remove" the global variable by deleting its
203*0b57cec5SDimitry Andric // initializer,
204*0b57cec5SDimitry Andric // making it external.
205*0b57cec5SDimitry Andric //
DeleteGlobalInitializer(GlobalVariable * GV)206*0b57cec5SDimitry Andric void llvm::DeleteGlobalInitializer(GlobalVariable *GV) {
207*0b57cec5SDimitry Andric   eliminateAliases(GV);
208*0b57cec5SDimitry Andric   GV->setInitializer(nullptr);
209*0b57cec5SDimitry Andric   GV->setComdat(nullptr);
210*0b57cec5SDimitry Andric }
211*0b57cec5SDimitry Andric 
212*0b57cec5SDimitry Andric // DeleteFunctionBody - "Remove" the function by deleting all of its basic
213*0b57cec5SDimitry Andric // blocks, making it external.
214*0b57cec5SDimitry Andric //
DeleteFunctionBody(Function * F)215*0b57cec5SDimitry Andric void llvm::DeleteFunctionBody(Function *F) {
216*0b57cec5SDimitry Andric   eliminateAliases(F);
217*0b57cec5SDimitry Andric   // Function declarations can't have comdats.
218*0b57cec5SDimitry Andric   F->setComdat(nullptr);
219*0b57cec5SDimitry Andric 
220*0b57cec5SDimitry Andric   // delete the body of the function...
221*0b57cec5SDimitry Andric   F->deleteBody();
222*0b57cec5SDimitry Andric   assert(F->isDeclaration() && "This didn't make the function external!");
223*0b57cec5SDimitry Andric }
224*0b57cec5SDimitry Andric 
225*0b57cec5SDimitry Andric /// GetTorInit - Given a list of entries for static ctors/dtors, return them
226*0b57cec5SDimitry Andric /// as a constant array.
GetTorInit(std::vector<std::pair<Function *,int>> & TorList)227*0b57cec5SDimitry Andric static Constant *GetTorInit(std::vector<std::pair<Function *, int>> &TorList) {
228*0b57cec5SDimitry Andric   assert(!TorList.empty() && "Don't create empty tor list!");
229*0b57cec5SDimitry Andric   std::vector<Constant *> ArrayElts;
230*0b57cec5SDimitry Andric   Type *Int32Ty = Type::getInt32Ty(TorList[0].first->getContext());
231*0b57cec5SDimitry Andric 
232*0b57cec5SDimitry Andric   StructType *STy = StructType::get(Int32Ty, TorList[0].first->getType());
233*0b57cec5SDimitry Andric   for (unsigned i = 0, e = TorList.size(); i != e; ++i) {
234*0b57cec5SDimitry Andric     Constant *Elts[] = {ConstantInt::get(Int32Ty, TorList[i].second),
235*0b57cec5SDimitry Andric                         TorList[i].first};
236*0b57cec5SDimitry Andric     ArrayElts.push_back(ConstantStruct::get(STy, Elts));
237*0b57cec5SDimitry Andric   }
238*0b57cec5SDimitry Andric   return ConstantArray::get(
239*0b57cec5SDimitry Andric       ArrayType::get(ArrayElts[0]->getType(), ArrayElts.size()), ArrayElts);
240*0b57cec5SDimitry Andric }
241*0b57cec5SDimitry Andric 
242*0b57cec5SDimitry Andric /// SplitStaticCtorDtor - A module was recently split into two parts, M1/M2, and
243*0b57cec5SDimitry Andric /// M1 has all of the global variables.  If M2 contains any functions that are
244*0b57cec5SDimitry Andric /// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and
245*0b57cec5SDimitry Andric /// prune appropriate entries out of M1s list.
SplitStaticCtorDtor(const char * GlobalName,Module * M1,Module * M2,ValueToValueMapTy & VMap)246*0b57cec5SDimitry Andric static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2,
247*0b57cec5SDimitry Andric                                 ValueToValueMapTy &VMap) {
248*0b57cec5SDimitry Andric   GlobalVariable *GV = M1->getNamedGlobal(GlobalName);
249*0b57cec5SDimitry Andric   if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() || !GV->use_empty())
250*0b57cec5SDimitry Andric     return;
251*0b57cec5SDimitry Andric 
252*0b57cec5SDimitry Andric   std::vector<std::pair<Function *, int>> M1Tors, M2Tors;
253*0b57cec5SDimitry Andric   ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
254*0b57cec5SDimitry Andric   if (!InitList)
255*0b57cec5SDimitry Andric     return;
256*0b57cec5SDimitry Andric 
257*0b57cec5SDimitry Andric   for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
258*0b57cec5SDimitry Andric     if (ConstantStruct *CS =
259*0b57cec5SDimitry Andric             dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
260*0b57cec5SDimitry Andric       if (CS->getNumOperands() != 2)
261*0b57cec5SDimitry Andric         return; // Not array of 2-element structs.
262*0b57cec5SDimitry Andric 
263*0b57cec5SDimitry Andric       if (CS->getOperand(1)->isNullValue())
264*0b57cec5SDimitry Andric         break; // Found a null terminator, stop here.
265*0b57cec5SDimitry Andric 
266*0b57cec5SDimitry Andric       ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
267*0b57cec5SDimitry Andric       int Priority = CI ? CI->getSExtValue() : 0;
268*0b57cec5SDimitry Andric 
269*0b57cec5SDimitry Andric       Constant *FP = CS->getOperand(1);
270*0b57cec5SDimitry Andric       if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
271*0b57cec5SDimitry Andric         if (CE->isCast())
272*0b57cec5SDimitry Andric           FP = CE->getOperand(0);
273*0b57cec5SDimitry Andric       if (Function *F = dyn_cast<Function>(FP)) {
274*0b57cec5SDimitry Andric         if (!F->isDeclaration())
275*0b57cec5SDimitry Andric           M1Tors.push_back(std::make_pair(F, Priority));
276*0b57cec5SDimitry Andric         else {
277*0b57cec5SDimitry Andric           // Map to M2's version of the function.
278*0b57cec5SDimitry Andric           F = cast<Function>(VMap[F]);
279*0b57cec5SDimitry Andric           M2Tors.push_back(std::make_pair(F, Priority));
280*0b57cec5SDimitry Andric         }
281*0b57cec5SDimitry Andric       }
282*0b57cec5SDimitry Andric     }
283*0b57cec5SDimitry Andric   }
284*0b57cec5SDimitry Andric 
285*0b57cec5SDimitry Andric   GV->eraseFromParent();
286*0b57cec5SDimitry Andric   if (!M1Tors.empty()) {
287*0b57cec5SDimitry Andric     Constant *M1Init = GetTorInit(M1Tors);
288*0b57cec5SDimitry Andric     new GlobalVariable(*M1, M1Init->getType(), false,
289*0b57cec5SDimitry Andric                        GlobalValue::AppendingLinkage, M1Init, GlobalName);
290*0b57cec5SDimitry Andric   }
291*0b57cec5SDimitry Andric 
292*0b57cec5SDimitry Andric   GV = M2->getNamedGlobal(GlobalName);
293*0b57cec5SDimitry Andric   assert(GV && "Not a clone of M1?");
294*0b57cec5SDimitry Andric   assert(GV->use_empty() && "llvm.ctors shouldn't have uses!");
295*0b57cec5SDimitry Andric 
296*0b57cec5SDimitry Andric   GV->eraseFromParent();
297*0b57cec5SDimitry Andric   if (!M2Tors.empty()) {
298*0b57cec5SDimitry Andric     Constant *M2Init = GetTorInit(M2Tors);
299*0b57cec5SDimitry Andric     new GlobalVariable(*M2, M2Init->getType(), false,
300*0b57cec5SDimitry Andric                        GlobalValue::AppendingLinkage, M2Init, GlobalName);
301*0b57cec5SDimitry Andric   }
302*0b57cec5SDimitry Andric }
303*0b57cec5SDimitry Andric 
304*0b57cec5SDimitry Andric std::unique_ptr<Module>
SplitFunctionsOutOfModule(Module * M,const std::vector<Function * > & F,ValueToValueMapTy & VMap)305*0b57cec5SDimitry Andric llvm::SplitFunctionsOutOfModule(Module *M, const std::vector<Function *> &F,
306*0b57cec5SDimitry Andric                                 ValueToValueMapTy &VMap) {
307*0b57cec5SDimitry Andric   // Make sure functions & globals are all external so that linkage
308*0b57cec5SDimitry Andric   // between the two modules will work.
309*0b57cec5SDimitry Andric   for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
310*0b57cec5SDimitry Andric     I->setLinkage(GlobalValue::ExternalLinkage);
311*0b57cec5SDimitry Andric   for (Module::global_iterator I = M->global_begin(), E = M->global_end();
312*0b57cec5SDimitry Andric        I != E; ++I) {
313*0b57cec5SDimitry Andric     if (I->hasName() && I->getName()[0] == '\01')
314*0b57cec5SDimitry Andric       I->setName(I->getName().substr(1));
315*0b57cec5SDimitry Andric     I->setLinkage(GlobalValue::ExternalLinkage);
316*0b57cec5SDimitry Andric   }
317*0b57cec5SDimitry Andric 
318*0b57cec5SDimitry Andric   ValueToValueMapTy NewVMap;
319*0b57cec5SDimitry Andric   std::unique_ptr<Module> New = CloneModule(*M, NewVMap);
320*0b57cec5SDimitry Andric 
321*0b57cec5SDimitry Andric   // Remove the Test functions from the Safe module
322*0b57cec5SDimitry Andric   std::set<Function *> TestFunctions;
323*0b57cec5SDimitry Andric   for (unsigned i = 0, e = F.size(); i != e; ++i) {
324*0b57cec5SDimitry Andric     Function *TNOF = cast<Function>(VMap[F[i]]);
325*0b57cec5SDimitry Andric     LLVM_DEBUG(errs() << "Removing function ");
326*0b57cec5SDimitry Andric     LLVM_DEBUG(TNOF->printAsOperand(errs(), false));
327*0b57cec5SDimitry Andric     LLVM_DEBUG(errs() << "\n");
328*0b57cec5SDimitry Andric     TestFunctions.insert(cast<Function>(NewVMap[TNOF]));
329*0b57cec5SDimitry Andric     DeleteFunctionBody(TNOF); // Function is now external in this module!
330*0b57cec5SDimitry Andric   }
331*0b57cec5SDimitry Andric 
332*0b57cec5SDimitry Andric   // Remove the Safe functions from the Test module
333*0b57cec5SDimitry Andric   for (Function &I : *New)
334*0b57cec5SDimitry Andric     if (!TestFunctions.count(&I))
335*0b57cec5SDimitry Andric       DeleteFunctionBody(&I);
336*0b57cec5SDimitry Andric 
337*0b57cec5SDimitry Andric   // Try to split the global initializers evenly
338*0b57cec5SDimitry Andric   for (GlobalVariable &I : M->globals()) {
339*0b57cec5SDimitry Andric     GlobalVariable *GV = cast<GlobalVariable>(NewVMap[&I]);
340*0b57cec5SDimitry Andric     if (Function *TestFn = globalInitUsesExternalBA(&I)) {
341*0b57cec5SDimitry Andric       if (Function *SafeFn = globalInitUsesExternalBA(GV)) {
342*0b57cec5SDimitry Andric         errs() << "*** Error: when reducing functions, encountered "
343*0b57cec5SDimitry Andric                   "the global '";
344*0b57cec5SDimitry Andric         GV->printAsOperand(errs(), false);
345*0b57cec5SDimitry Andric         errs() << "' with an initializer that references blockaddresses "
346*0b57cec5SDimitry Andric                   "from safe function '"
347*0b57cec5SDimitry Andric                << SafeFn->getName() << "' and from test function '"
348*0b57cec5SDimitry Andric                << TestFn->getName() << "'.\n";
349*0b57cec5SDimitry Andric         exit(1);
350*0b57cec5SDimitry Andric       }
351*0b57cec5SDimitry Andric       DeleteGlobalInitializer(&I); // Delete the initializer to make it external
352*0b57cec5SDimitry Andric     } else {
353*0b57cec5SDimitry Andric       // If we keep it in the safe module, then delete it in the test module
354*0b57cec5SDimitry Andric       DeleteGlobalInitializer(GV);
355*0b57cec5SDimitry Andric     }
356*0b57cec5SDimitry Andric   }
357*0b57cec5SDimitry Andric 
358*0b57cec5SDimitry Andric   // Make sure that there is a global ctor/dtor array in both halves of the
359*0b57cec5SDimitry Andric   // module if they both have static ctor/dtor functions.
360*0b57cec5SDimitry Andric   SplitStaticCtorDtor("llvm.global_ctors", M, New.get(), NewVMap);
361*0b57cec5SDimitry Andric   SplitStaticCtorDtor("llvm.global_dtors", M, New.get(), NewVMap);
362*0b57cec5SDimitry Andric 
363*0b57cec5SDimitry Andric   return New;
364*0b57cec5SDimitry Andric }
365*0b57cec5SDimitry Andric 
366*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
367*0b57cec5SDimitry Andric // Basic Block Extraction Code
368*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
369*0b57cec5SDimitry Andric 
370*0b57cec5SDimitry Andric std::unique_ptr<Module>
extractMappedBlocksFromModule(const std::vector<BasicBlock * > & BBs,Module * M)371*0b57cec5SDimitry Andric BugDriver::extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs,
372*0b57cec5SDimitry Andric                                          Module *M) {
373*0b57cec5SDimitry Andric   auto Temp = sys::fs::TempFile::create(OutputPrefix + "-extractblocks%%%%%%%");
374*0b57cec5SDimitry Andric   if (!Temp) {
375*0b57cec5SDimitry Andric     outs() << "*** Basic Block extraction failed!\n";
376*0b57cec5SDimitry Andric     errs() << "Error creating temporary file: " << toString(Temp.takeError())
377*0b57cec5SDimitry Andric            << "\n";
378*0b57cec5SDimitry Andric     EmitProgressBitcode(*M, "basicblockextractfail", true);
379*0b57cec5SDimitry Andric     return nullptr;
380*0b57cec5SDimitry Andric   }
381*0b57cec5SDimitry Andric   DiscardTemp Discard{*Temp};
382*0b57cec5SDimitry Andric 
383*0b57cec5SDimitry Andric   // Extract all of the blocks except the ones in BBs.
384*0b57cec5SDimitry Andric   SmallVector<BasicBlock *, 32> BlocksToExtract;
385*0b57cec5SDimitry Andric   for (Function &F : *M)
386*0b57cec5SDimitry Andric     for (BasicBlock &BB : F)
387*0b57cec5SDimitry Andric       // Check if this block is going to be extracted.
388e8d8bef9SDimitry Andric       if (!llvm::is_contained(BBs, &BB))
389*0b57cec5SDimitry Andric         BlocksToExtract.push_back(&BB);
390*0b57cec5SDimitry Andric 
391*0b57cec5SDimitry Andric   raw_fd_ostream OS(Temp->FD, /*shouldClose*/ false);
392*0b57cec5SDimitry Andric   for (BasicBlock *BB : BBs) {
393*0b57cec5SDimitry Andric     // If the BB doesn't have a name, give it one so we have something to key
394*0b57cec5SDimitry Andric     // off of.
395*0b57cec5SDimitry Andric     if (!BB->hasName())
396*0b57cec5SDimitry Andric       BB->setName("tmpbb");
397*0b57cec5SDimitry Andric     OS << BB->getParent()->getName() << " " << BB->getName() << "\n";
398*0b57cec5SDimitry Andric   }
399*0b57cec5SDimitry Andric   OS.flush();
400*0b57cec5SDimitry Andric   if (OS.has_error()) {
401*0b57cec5SDimitry Andric     errs() << "Error writing list of blocks to not extract\n";
402*0b57cec5SDimitry Andric     EmitProgressBitcode(*M, "basicblockextractfail", true);
403*0b57cec5SDimitry Andric     OS.clear_error();
404*0b57cec5SDimitry Andric     return nullptr;
405*0b57cec5SDimitry Andric   }
406*0b57cec5SDimitry Andric 
407*0b57cec5SDimitry Andric   std::string uniqueFN = "--extract-blocks-file=";
408*0b57cec5SDimitry Andric   uniqueFN += Temp->TmpName;
409*0b57cec5SDimitry Andric 
410*0b57cec5SDimitry Andric   std::vector<std::string> PI;
411*0b57cec5SDimitry Andric   PI.push_back("extract-blocks");
4128bcb0991SDimitry Andric   std::unique_ptr<Module> Ret = runPassesOn(M, PI, {uniqueFN});
413*0b57cec5SDimitry Andric 
414*0b57cec5SDimitry Andric   if (!Ret) {
415*0b57cec5SDimitry Andric     outs() << "*** Basic Block extraction failed, please report a bug!\n";
416*0b57cec5SDimitry Andric     EmitProgressBitcode(*M, "basicblockextractfail", true);
417*0b57cec5SDimitry Andric   }
418*0b57cec5SDimitry Andric   return Ret;
419*0b57cec5SDimitry Andric }
420