173a6bdd9SChris Lattner //===- ExtractFunction.cpp - Extract a function from Program --------------===//
273a6bdd9SChris Lattner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609344dcfSJohn Criswell //
709344dcfSJohn Criswell //===----------------------------------------------------------------------===//
809344dcfSJohn Criswell //
9fd72bed3SChris Lattner // This file implements several methods that are used to extract functions,
10fd72bed3SChris Lattner // loops, or portions of a module from the rest of the module.
1173a6bdd9SChris Lattner //
1273a6bdd9SChris Lattner //===----------------------------------------------------------------------===//
1373a6bdd9SChris Lattner
1473a6bdd9SChris Lattner #include "BugDriver.h"
159fb823bbSChandler Carruth #include "llvm/IR/Constants.h"
169fb823bbSChandler Carruth #include "llvm/IR/DataLayout.h"
179fb823bbSChandler Carruth #include "llvm/IR/DerivedTypes.h"
189fb823bbSChandler Carruth #include "llvm/IR/LLVMContext.h"
1930d69c2eSChandler Carruth #include "llvm/IR/LegacyPassManager.h"
209fb823bbSChandler Carruth #include "llvm/IR/Module.h"
215ad5f15cSChandler Carruth #include "llvm/IR/Verifier.h"
22ef432703SBrian Gaeke #include "llvm/Pass.h"
234d88a1c2SChandler Carruth #include "llvm/Support/CommandLine.h"
244d88a1c2SChandler Carruth #include "llvm/Support/Debug.h"
254d88a1c2SChandler Carruth #include "llvm/Support/FileUtilities.h"
264d88a1c2SChandler Carruth #include "llvm/Support/Path.h"
274d88a1c2SChandler Carruth #include "llvm/Support/Signals.h"
284d88a1c2SChandler Carruth #include "llvm/Support/ToolOutputFile.h"
2973a6bdd9SChris Lattner #include "llvm/Transforms/IPO.h"
300eb5ce94SChris Lattner #include "llvm/Transforms/Scalar.h"
3173a6bdd9SChris Lattner #include "llvm/Transforms/Utils/Cloning.h"
320fde0015SChandler Carruth #include "llvm/Transforms/Utils/CodeExtractor.h"
333838243dSChris Lattner #include <set>
343f1ad878SChris Lattner using namespace llvm;
35960707c3SBrian Gaeke
36e96dd897SChandler Carruth #define DEBUG_TYPE "bugpoint"
37e96dd897SChandler Carruth
38960707c3SBrian Gaeke namespace llvm {
39d1e2aaefSChris Lattner bool DisableSimplifyCFG = false;
40a53337f7SDaniel Dunbar extern cl::opt<std::string> OutputPrefix;
41960707c3SBrian Gaeke } // End llvm namespace
42960707c3SBrian Gaeke
438d8de422SChris Lattner namespace {
448d0a0811SJustin Bogner cl::opt<bool> NoDCE("disable-dce",
458d8de422SChris Lattner cl::desc("Do not use the -dce pass to reduce testcases"));
46d1e2aaefSChris Lattner cl::opt<bool, true>
47d1e2aaefSChris Lattner NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG),
488d8de422SChris Lattner cl::desc("Do not use the -simplifycfg pass to reduce testcases"));
499f18ea84SEli Friedman
globalInitUsesExternalBA(GlobalVariable * GV)509f18ea84SEli Friedman Function *globalInitUsesExternalBA(GlobalVariable *GV) {
519f18ea84SEli Friedman if (!GV->hasInitializer())
52e6cb63e4SCraig Topper return nullptr;
539f18ea84SEli Friedman
549f18ea84SEli Friedman Constant *I = GV->getInitializer();
559f18ea84SEli Friedman
569f18ea84SEli Friedman // walk the values used by the initializer
579f18ea84SEli Friedman // (and recurse into things like ConstantExpr)
589f18ea84SEli Friedman std::vector<Constant *> Todo;
599f18ea84SEli Friedman std::set<Constant *> Done;
609f18ea84SEli Friedman Todo.push_back(I);
619f18ea84SEli Friedman
629f18ea84SEli Friedman while (!Todo.empty()) {
639f18ea84SEli Friedman Constant *V = Todo.back();
649f18ea84SEli Friedman Todo.pop_back();
659f18ea84SEli Friedman Done.insert(V);
669f18ea84SEli Friedman
679f18ea84SEli Friedman if (BlockAddress *BA = dyn_cast<BlockAddress>(V)) {
689f18ea84SEli Friedman Function *F = BA->getFunction();
699f18ea84SEli Friedman if (F->isDeclaration())
709f18ea84SEli Friedman return F;
718d8de422SChris Lattner }
7273a6bdd9SChris Lattner
739f18ea84SEli Friedman for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) {
749f18ea84SEli Friedman Constant *C = dyn_cast<Constant>(*i);
759f18ea84SEli Friedman if (C && !isa<GlobalValue>(C) && !Done.count(C))
769f18ea84SEli Friedman Todo.push_back(C);
779f18ea84SEli Friedman }
789f18ea84SEli Friedman }
79e6cb63e4SCraig Topper return nullptr;
809f18ea84SEli Friedman }
819f18ea84SEli Friedman } // end anonymous namespace
829f18ea84SEli Friedman
8328b351a5SRafael Espindola std::unique_ptr<Module>
deleteInstructionFromProgram(const Instruction * I,unsigned Simplification)8428b351a5SRafael Espindola BugDriver::deleteInstructionFromProgram(const Instruction *I,
85d1e241a4SRafael Espindola unsigned Simplification) {
86d1e241a4SRafael Espindola // FIXME, use vmap?
8771867532SRafael Espindola std::unique_ptr<Module> Clone = CloneModule(*Program);
880eb5ce94SChris Lattner
89b943b6b0SChris Lattner const BasicBlock *PBB = I->getParent();
90b943b6b0SChris Lattner const Function *PF = PBB->getParent();
910eb5ce94SChris Lattner
92d1e241a4SRafael Espindola Module::iterator RFI = Clone->begin(); // Get iterator to corresponding fn
938d0a0811SJustin Bogner std::advance(
948d0a0811SJustin Bogner RFI, std::distance(PF->getParent()->begin(), Module::const_iterator(PF)));
950eb5ce94SChris Lattner
960eb5ce94SChris Lattner Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB
97b943b6b0SChris Lattner std::advance(RBI, std::distance(PF->begin(), Function::const_iterator(PBB)));
980eb5ce94SChris Lattner
990eb5ce94SChris Lattner BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst
100b943b6b0SChris Lattner std::advance(RI, std::distance(PBB->begin(), BasicBlock::const_iterator(I)));
101306d16e0SDuncan P. N. Exon Smith Instruction *TheInst = &*RI; // Got the corresponding instruction!
1020eb5ce94SChris Lattner
1030eb5ce94SChris Lattner // If this instruction produces a value, replace any users with null values
10434a2249fSDan Gohman if (!TheInst->getType()->isVoidTy())
1055a1acd99SOwen Anderson TheInst->replaceAllUsesWith(Constant::getNullValue(TheInst->getType()));
1060eb5ce94SChris Lattner
1070eb5ce94SChris Lattner // Remove the instruction from the program.
108b943b6b0SChris Lattner TheInst->getParent()->getInstList().erase(TheInst);
1090eb5ce94SChris Lattner
11010c0469bSChris Lattner // Spiff up the output a little bit.
111d1e241a4SRafael Espindola std::vector<std::string> Passes;
112f3e8f97dSChris Lattner
113d1e241a4SRafael Espindola /// Can we get rid of the -disable-* options?
1148d8de422SChris Lattner if (Simplification > 1 && !NoDCE)
115d1e241a4SRafael Espindola Passes.push_back("dce");
116d1e2aaefSChris Lattner if (Simplification && !DisableSimplifyCFG)
117d1e241a4SRafael Espindola Passes.push_back("simplifycfg"); // Delete dead control flow
11844ffd7c3SChris Lattner
119d1e241a4SRafael Espindola Passes.push_back("verify");
120e84e7675SVedant Kumar std::unique_ptr<Module> New = runPassesOn(Clone.get(), Passes);
121d1e241a4SRafael Espindola if (!New) {
122d1e241a4SRafael Espindola errs() << "Instruction removal failed. Sorry. :( Please report a bug!\n";
123d1e241a4SRafael Espindola exit(1);
124d1e241a4SRafael Espindola }
125d1e241a4SRafael Espindola return New;
1260eb5ce94SChris Lattner }
127514c02ebSChris Lattner
12828b351a5SRafael Espindola std::unique_ptr<Module>
performFinalCleanups(std::unique_ptr<Module> M,bool MayModifySemantics)129b71251caSRafael Espindola BugDriver::performFinalCleanups(std::unique_ptr<Module> M,
130b71251caSRafael Espindola bool MayModifySemantics) {
1312b3ab562SChris Lattner // Make all functions external, so GlobalDCE doesn't delete them...
1322b3ab562SChris Lattner for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
1332b3ab562SChris Lattner I->setLinkage(GlobalValue::ExternalLinkage);
1342b3ab562SChris Lattner
13533e81a82SRafael Espindola std::vector<std::string> CleanupPasses;
13633e81a82SRafael Espindola CleanupPasses.push_back("globaldce");
1373f1ad878SChris Lattner
1383f1ad878SChris Lattner if (MayModifySemantics)
13933e81a82SRafael Espindola CleanupPasses.push_back("deadarghaX0r");
1403f1ad878SChris Lattner else
14133e81a82SRafael Espindola CleanupPasses.push_back("deadargelim");
1422920100eSChris Lattner
143b71251caSRafael Espindola std::unique_ptr<Module> New = runPassesOn(M.get(), CleanupPasses);
144e6cb63e4SCraig Topper if (!New) {
145d8db3760SDan Gohman errs() << "Final cleanups failed. Sorry. :( Please report a bug!\n";
14628b351a5SRafael Espindola return nullptr;
1476ce2d033SChris Lattner }
1486ce2d033SChris Lattner return New;
149514c02ebSChris Lattner }
150567543f0SChris Lattner
extractLoop(Module * M)15128b351a5SRafael Espindola std::unique_ptr<Module> BugDriver::extractLoop(Module *M) {
15233e81a82SRafael Espindola std::vector<std::string> LoopExtractPasses;
15333e81a82SRafael Espindola LoopExtractPasses.push_back("loop-extract-single");
1543fe96bc9SChris Lattner
15528b351a5SRafael Espindola std::unique_ptr<Module> NewM = runPassesOn(M, LoopExtractPasses);
156e6cb63e4SCraig Topper if (!NewM) {
157ee05152cSDan Gohman outs() << "*** Loop extraction failed: ";
158f6074ed9SRafael Espindola EmitProgressBitcode(*M, "loopextraction", true);
159ee05152cSDan Gohman outs() << "*** Sorry. :( Please report a bug!\n";
160e6cb63e4SCraig Topper return nullptr;
1613fe96bc9SChris Lattner }
1623fe96bc9SChris Lattner
1633fe96bc9SChris Lattner // Check to see if we created any new functions. If not, no loops were
1648cb483b3SChris Lattner // extracted and we should return null. Limit the number of loops we extract
1658cb483b3SChris Lattner // to avoid taking forever.
1668cb483b3SChris Lattner static unsigned NumExtracted = 32;
167d308797cSChris Lattner if (M->size() == NewM->size() || --NumExtracted == 0) {
168e6cb63e4SCraig Topper return nullptr;
169d308797cSChris Lattner } else {
170d308797cSChris Lattner assert(M->size() < NewM->size() && "Loop extract removed functions?");
171d308797cSChris Lattner Module::iterator MI = NewM->begin();
172d308797cSChris Lattner for (unsigned i = 0, e = M->size(); i != e; ++i)
173d308797cSChris Lattner ++MI;
1743fe96bc9SChris Lattner }
1753fe96bc9SChris Lattner
1763fe96bc9SChris Lattner return NewM;
1773fe96bc9SChris Lattner }
1783fe96bc9SChris Lattner
eliminateAliases(GlobalValue * GV)17928ad2b47SHal Finkel static void eliminateAliases(GlobalValue *GV) {
18028ad2b47SHal Finkel // First, check whether a GlobalAlias references this definition.
18128ad2b47SHal Finkel // GlobalAlias MAY NOT reference declarations.
18228ad2b47SHal Finkel for (;;) {
18328ad2b47SHal Finkel // 1. Find aliases
18428ad2b47SHal Finkel SmallVector<GlobalAlias *, 1> aliases;
18528ad2b47SHal Finkel Module *M = GV->getParent();
1868d0a0811SJustin Bogner for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end();
1878d0a0811SJustin Bogner I != E; ++I)
18828ad2b47SHal Finkel if (I->getAliasee()->stripPointerCasts() == GV)
18928ad2b47SHal Finkel aliases.push_back(&*I);
19028ad2b47SHal Finkel if (aliases.empty())
19128ad2b47SHal Finkel break;
19228ad2b47SHal Finkel // 2. Resolve aliases
19328ad2b47SHal Finkel for (unsigned i = 0, e = aliases.size(); i < e; ++i) {
19428ad2b47SHal Finkel aliases[i]->replaceAllUsesWith(aliases[i]->getAliasee());
19528ad2b47SHal Finkel aliases[i]->eraseFromParent();
19628ad2b47SHal Finkel }
19728ad2b47SHal Finkel // 3. Repeat until no more aliases found; there might
19828ad2b47SHal Finkel // be an alias to an alias...
19928ad2b47SHal Finkel }
20028ad2b47SHal Finkel }
20128ad2b47SHal Finkel
20228ad2b47SHal Finkel //
2038d0a0811SJustin Bogner // DeleteGlobalInitializer - "Remove" the global variable by deleting its
2048d0a0811SJustin Bogner // initializer,
20528ad2b47SHal Finkel // making it external.
20628ad2b47SHal Finkel //
DeleteGlobalInitializer(GlobalVariable * GV)20728ad2b47SHal Finkel void llvm::DeleteGlobalInitializer(GlobalVariable *GV) {
20828ad2b47SHal Finkel eliminateAliases(GV);
20928ad2b47SHal Finkel GV->setInitializer(nullptr);
21055379ab8SHal Finkel GV->setComdat(nullptr);
21128ad2b47SHal Finkel }
2123fe96bc9SChris Lattner
213567543f0SChris Lattner // DeleteFunctionBody - "Remove" the function by deleting all of its basic
214567543f0SChris Lattner // blocks, making it external.
215567543f0SChris Lattner //
DeleteFunctionBody(Function * F)216567543f0SChris Lattner void llvm::DeleteFunctionBody(Function *F) {
21728ad2b47SHal Finkel eliminateAliases(F);
2182a445cf7SJustin Lebar // Function declarations can't have comdats.
2192a445cf7SJustin Lebar F->setComdat(nullptr);
22028ad2b47SHal Finkel
221567543f0SChris Lattner // delete the body of the function...
222567543f0SChris Lattner F->deleteBody();
2235301e7c6SReid Spencer assert(F->isDeclaration() && "This didn't make the function external!");
224567543f0SChris Lattner }
225567543f0SChris Lattner
226fdb533a1SChris Lattner /// GetTorInit - Given a list of entries for static ctors/dtors, return them
227fdb533a1SChris Lattner /// as a constant array.
GetTorInit(std::vector<std::pair<Function *,int>> & TorList)228fdb533a1SChris Lattner static Constant *GetTorInit(std::vector<std::pair<Function *, int>> &TorList) {
229fdb533a1SChris Lattner assert(!TorList.empty() && "Don't create empty tor list!");
230fdb533a1SChris Lattner std::vector<Constant *> ArrayElts;
231b804a2b7SJay Foad Type *Int32Ty = Type::getInt32Ty(TorList[0].first->getContext());
232cc19efaaSChris Lattner
233e38003f8SSerge Guelton StructType *STy = StructType::get(Int32Ty, TorList[0].first->getType());
234fdb533a1SChris Lattner for (unsigned i = 0, e = TorList.size(); i != e; ++i) {
2358d0a0811SJustin Bogner Constant *Elts[] = {ConstantInt::get(Int32Ty, TorList[i].second),
2368d0a0811SJustin Bogner TorList[i].first};
237cc19efaaSChris Lattner ArrayElts.push_back(ConstantStruct::get(STy, Elts));
238fdb533a1SChris Lattner }
2398d0a0811SJustin Bogner return ConstantArray::get(
2408d0a0811SJustin Bogner ArrayType::get(ArrayElts[0]->getType(), ArrayElts.size()), ArrayElts);
241fdb533a1SChris Lattner }
242fdb533a1SChris Lattner
243fdb533a1SChris Lattner /// SplitStaticCtorDtor - A module was recently split into two parts, M1/M2, and
244fdb533a1SChris Lattner /// M1 has all of the global variables. If M2 contains any functions that are
245fdb533a1SChris Lattner /// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and
246fdb533a1SChris Lattner /// prune appropriate entries out of M1s list.
SplitStaticCtorDtor(const char * GlobalName,Module * M1,Module * M2,ValueToValueMapTy & VMap)247956ae9dcSDan Gohman static void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2,
248229e38f0SRafael Espindola ValueToValueMapTy &VMap) {
249fdb533a1SChris Lattner GlobalVariable *GV = M1->getNamedGlobal(GlobalName);
2508d0a0811SJustin Bogner if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() || !GV->use_empty())
2518d0a0811SJustin Bogner return;
252fdb533a1SChris Lattner
253fdb533a1SChris Lattner std::vector<std::pair<Function *, int>> M1Tors, M2Tors;
254fdb533a1SChris Lattner ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
2558d0a0811SJustin Bogner if (!InitList)
2568d0a0811SJustin Bogner return;
257fdb533a1SChris Lattner
258fdb533a1SChris Lattner for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
2598d0a0811SJustin Bogner if (ConstantStruct *CS =
2608d0a0811SJustin Bogner dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
2618d0a0811SJustin Bogner if (CS->getNumOperands() != 2)
2628d0a0811SJustin Bogner return; // Not array of 2-element structs.
263fdb533a1SChris Lattner
264fdb533a1SChris Lattner if (CS->getOperand(1)->isNullValue())
265fdb533a1SChris Lattner break; // Found a null terminator, stop here.
266fdb533a1SChris Lattner
267e0fc4dfcSReid Spencer ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
268e0fc4dfcSReid Spencer int Priority = CI ? CI->getSExtValue() : 0;
269fdb533a1SChris Lattner
270fdb533a1SChris Lattner Constant *FP = CS->getOperand(1);
271fdb533a1SChris Lattner if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
2726c38f0bbSReid Spencer if (CE->isCast())
273fdb533a1SChris Lattner FP = CE->getOperand(0);
274fdb533a1SChris Lattner if (Function *F = dyn_cast<Function>(FP)) {
2755301e7c6SReid Spencer if (!F->isDeclaration())
276fdb533a1SChris Lattner M1Tors.push_back(std::make_pair(F, Priority));
277fdb533a1SChris Lattner else {
278fdb533a1SChris Lattner // Map to M2's version of the function.
2790dc3c2d3SDevang Patel F = cast<Function>(VMap[F]);
280fdb533a1SChris Lattner M2Tors.push_back(std::make_pair(F, Priority));
281fdb533a1SChris Lattner }
282fdb533a1SChris Lattner }
283fdb533a1SChris Lattner }
284fdb533a1SChris Lattner }
285fdb533a1SChris Lattner
286fdb533a1SChris Lattner GV->eraseFromParent();
287fdb533a1SChris Lattner if (!M1Tors.empty()) {
288fdb533a1SChris Lattner Constant *M1Init = GetTorInit(M1Tors);
289b17f3294SOwen Anderson new GlobalVariable(*M1, M1Init->getType(), false,
2908d0a0811SJustin Bogner GlobalValue::AppendingLinkage, M1Init, GlobalName);
291fdb533a1SChris Lattner }
292fdb533a1SChris Lattner
293fdb533a1SChris Lattner GV = M2->getNamedGlobal(GlobalName);
294fdb533a1SChris Lattner assert(GV && "Not a clone of M1?");
295fdb533a1SChris Lattner assert(GV->use_empty() && "llvm.ctors shouldn't have uses!");
296fdb533a1SChris Lattner
297fdb533a1SChris Lattner GV->eraseFromParent();
298fdb533a1SChris Lattner if (!M2Tors.empty()) {
299fdb533a1SChris Lattner Constant *M2Init = GetTorInit(M2Tors);
300b17f3294SOwen Anderson new GlobalVariable(*M2, M2Init->getType(), false,
3018d0a0811SJustin Bogner GlobalValue::AppendingLinkage, M2Init, GlobalName);
302fdb533a1SChris Lattner }
303fdb533a1SChris Lattner }
304fdb533a1SChris Lattner
30550102c29SRafael Espindola std::unique_ptr<Module>
SplitFunctionsOutOfModule(Module * M,const std::vector<Function * > & F,ValueToValueMapTy & VMap)30650102c29SRafael Espindola llvm::SplitFunctionsOutOfModule(Module *M, const std::vector<Function *> &F,
307229e38f0SRafael Espindola ValueToValueMapTy &VMap) {
308567543f0SChris Lattner // Make sure functions & globals are all external so that linkage
309567543f0SChris Lattner // between the two modules will work.
310567543f0SChris Lattner for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
311567543f0SChris Lattner I->setLinkage(GlobalValue::ExternalLinkage);
312fdb533a1SChris Lattner for (Module::global_iterator I = M->global_begin(), E = M->global_end();
313c76bacbfSOwen Anderson I != E; ++I) {
314d786b51eSDaniel Dunbar if (I->hasName() && I->getName()[0] == '\01')
315d786b51eSDaniel Dunbar I->setName(I->getName().substr(1));
316567543f0SChris Lattner I->setLinkage(GlobalValue::ExternalLinkage);
317c76bacbfSOwen Anderson }
318567543f0SChris Lattner
319229e38f0SRafael Espindola ValueToValueMapTy NewVMap;
32071867532SRafael Espindola std::unique_ptr<Module> New = CloneModule(*M, NewVMap);
321567543f0SChris Lattner
3227275b02eSChris Lattner // Remove the Test functions from the Safe module
323956ae9dcSDan Gohman std::set<Function *> TestFunctions;
324567543f0SChris Lattner for (unsigned i = 0, e = F.size(); i != e; ++i) {
3250dc3c2d3SDevang Patel Function *TNOF = cast<Function>(VMap[F[i]]);
326d34e60caSNicola Zaghen LLVM_DEBUG(errs() << "Removing function ");
327d34e60caSNicola Zaghen LLVM_DEBUG(TNOF->printAsOperand(errs(), false));
328d34e60caSNicola Zaghen LLVM_DEBUG(errs() << "\n");
3290dc3c2d3SDevang Patel TestFunctions.insert(cast<Function>(NewVMap[TNOF]));
3307275b02eSChris Lattner DeleteFunctionBody(TNOF); // Function is now external in this module!
331567543f0SChris Lattner }
332567543f0SChris Lattner
3337275b02eSChris Lattner // Remove the Safe functions from the Test module
334306d16e0SDuncan P. N. Exon Smith for (Function &I : *New)
335306d16e0SDuncan P. N. Exon Smith if (!TestFunctions.count(&I))
336306d16e0SDuncan P. N. Exon Smith DeleteFunctionBody(&I);
337fdb533a1SChris Lattner
3389f18ea84SEli Friedman // Try to split the global initializers evenly
339306d16e0SDuncan P. N. Exon Smith for (GlobalVariable &I : M->globals()) {
340306d16e0SDuncan P. N. Exon Smith GlobalVariable *GV = cast<GlobalVariable>(NewVMap[&I]);
341306d16e0SDuncan P. N. Exon Smith if (Function *TestFn = globalInitUsesExternalBA(&I)) {
3429f18ea84SEli Friedman if (Function *SafeFn = globalInitUsesExternalBA(GV)) {
3439f18ea84SEli Friedman errs() << "*** Error: when reducing functions, encountered "
3449f18ea84SEli Friedman "the global '";
345d48cdbf0SChandler Carruth GV->printAsOperand(errs(), false);
3469f18ea84SEli Friedman errs() << "' with an initializer that references blockaddresses "
3478d0a0811SJustin Bogner "from safe function '"
3488d0a0811SJustin Bogner << SafeFn->getName() << "' and from test function '"
3498d0a0811SJustin Bogner << TestFn->getName() << "'.\n";
3509f18ea84SEli Friedman exit(1);
3519f18ea84SEli Friedman }
35228ad2b47SHal Finkel DeleteGlobalInitializer(&I); // Delete the initializer to make it external
3539f18ea84SEli Friedman } else {
3549f18ea84SEli Friedman // If we keep it in the safe module, then delete it in the test module
35528ad2b47SHal Finkel DeleteGlobalInitializer(GV);
3569f18ea84SEli Friedman }
3579f18ea84SEli Friedman }
3589f18ea84SEli Friedman
359fdb533a1SChris Lattner // Make sure that there is a global ctor/dtor array in both halves of the
360fdb533a1SChris Lattner // module if they both have static ctor/dtor functions.
36150102c29SRafael Espindola SplitStaticCtorDtor("llvm.global_ctors", M, New.get(), NewVMap);
36250102c29SRafael Espindola SplitStaticCtorDtor("llvm.global_dtors", M, New.get(), NewVMap);
363fdb533a1SChris Lattner
364567543f0SChris Lattner return New;
365567543f0SChris Lattner }
366a060b10eSChris Lattner
367a060b10eSChris Lattner //===----------------------------------------------------------------------===//
368a060b10eSChris Lattner // Basic Block Extraction Code
369a060b10eSChris Lattner //===----------------------------------------------------------------------===//
370a060b10eSChris Lattner
37128b351a5SRafael Espindola std::unique_ptr<Module>
extractMappedBlocksFromModule(const std::vector<BasicBlock * > & BBs,Module * M)37228b351a5SRafael Espindola BugDriver::extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs,
373a060b10eSChris Lattner Module *M) {
3748010bf0aSRafael Espindola auto Temp = sys::fs::TempFile::create(OutputPrefix + "-extractblocks%%%%%%%");
3758010bf0aSRafael Espindola if (!Temp) {
376ee05152cSDan Gohman outs() << "*** Basic Block extraction failed!\n";
3778010bf0aSRafael Espindola errs() << "Error creating temporary file: " << toString(Temp.takeError())
3788010bf0aSRafael Espindola << "\n";
379f6074ed9SRafael Espindola EmitProgressBitcode(*M, "basicblockextractfail", true);
380e6cb63e4SCraig Topper return nullptr;
381c6243020SNick Lewycky }
3828010bf0aSRafael Espindola DiscardTemp Discard{*Temp};
383c6243020SNick Lewycky
384dc40be75SVolkan Keles // Extract all of the blocks except the ones in BBs.
385dc40be75SVolkan Keles SmallVector<BasicBlock *, 32> BlocksToExtract;
386dc40be75SVolkan Keles for (Function &F : *M)
387dc40be75SVolkan Keles for (BasicBlock &BB : F)
388dc40be75SVolkan Keles // Check if this block is going to be extracted.
389*902cbcd5SKazu Hirata if (!llvm::is_contained(BBs, &BB))
390dc40be75SVolkan Keles BlocksToExtract.push_back(&BB);
391dc40be75SVolkan Keles
3928010bf0aSRafael Espindola raw_fd_ostream OS(Temp->FD, /*shouldClose*/ false);
393dc40be75SVolkan Keles for (BasicBlock *BB : BBs) {
39497879424SChris Lattner // If the BB doesn't have a name, give it one so we have something to key
39597879424SChris Lattner // off of.
3968d0a0811SJustin Bogner if (!BB->hasName())
3978d0a0811SJustin Bogner BB->setName("tmpbb");
3988010bf0aSRafael Espindola OS << BB->getParent()->getName() << " " << BB->getName() << "\n";
399c6243020SNick Lewycky }
4008010bf0aSRafael Espindola OS.flush();
4018010bf0aSRafael Espindola if (OS.has_error()) {
4027e936eeeSRafael Espindola errs() << "Error writing list of blocks to not extract\n";
403f6074ed9SRafael Espindola EmitProgressBitcode(*M, "basicblockextractfail", true);
4048010bf0aSRafael Espindola OS.clear_error();
405e6cb63e4SCraig Topper return nullptr;
4068525fe71SDan Gohman }
407c6243020SNick Lewycky
4087e936eeeSRafael Espindola std::string uniqueFN = "--extract-blocks-file=";
4098010bf0aSRafael Espindola uniqueFN += Temp->TmpName;
410c6243020SNick Lewycky
41133e81a82SRafael Espindola std::vector<std::string> PI;
41233e81a82SRafael Espindola PI.push_back("extract-blocks");
413f341f801SFlorian Hahn std::unique_ptr<Module> Ret = runPassesOn(M, PI, {uniqueFN});
414c6243020SNick Lewycky
415e6cb63e4SCraig Topper if (!Ret) {
416ee05152cSDan Gohman outs() << "*** Basic Block extraction failed, please report a bug!\n";
417f6074ed9SRafael Espindola EmitProgressBitcode(*M, "basicblockextractfail", true);
418af32dfa0SChris Lattner }
419a060b10eSChris Lattner return Ret;
420a060b10eSChris Lattner }
421