1193323Sed//===- ExtractFunction.cpp - Extract a function from Program --------------===//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9193323Sed//
10193323Sed// This file implements several methods that are used to extract functions,
11193323Sed// loops, or portions of a module from the rest of the module.
12193323Sed//
13193323Sed//===----------------------------------------------------------------------===//
14193323Sed
15193323Sed#include "BugDriver.h"
16249423Sdim#include "llvm/IR/Constants.h"
17249423Sdim#include "llvm/IR/DataLayout.h"
18249423Sdim#include "llvm/IR/DerivedTypes.h"
19249423Sdim#include "llvm/IR/LLVMContext.h"
20288943Sdim#include "llvm/IR/LegacyPassManager.h"
21249423Sdim#include "llvm/IR/Module.h"
22276479Sdim#include "llvm/IR/Verifier.h"
23249423Sdim#include "llvm/Pass.h"
24193323Sed#include "llvm/Support/CommandLine.h"
25193323Sed#include "llvm/Support/Debug.h"
26193323Sed#include "llvm/Support/FileUtilities.h"
27218885Sdim#include "llvm/Support/Path.h"
28218885Sdim#include "llvm/Support/Signals.h"
29249423Sdim#include "llvm/Support/ToolOutputFile.h"
30249423Sdim#include "llvm/Transforms/IPO.h"
31249423Sdim#include "llvm/Transforms/Scalar.h"
32249423Sdim#include "llvm/Transforms/Utils/Cloning.h"
33249423Sdim#include "llvm/Transforms/Utils/CodeExtractor.h"
34193323Sed#include <set>
35193323Sedusing namespace llvm;
36193323Sed
37276479Sdim#define DEBUG_TYPE "bugpoint"
38276479Sdim
39193323Sednamespace llvm {
40193323Sed  bool DisableSimplifyCFG = false;
41198090Srdivacky  extern cl::opt<std::string> OutputPrefix;
42193323Sed} // End llvm namespace
43193323Sed
44193323Sednamespace {
45193323Sed  cl::opt<bool>
46193323Sed  NoDCE ("disable-dce",
47193323Sed         cl::desc("Do not use the -dce pass to reduce testcases"));
48193323Sed  cl::opt<bool, true>
49193323Sed  NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG),
50193323Sed         cl::desc("Do not use the -simplifycfg pass to reduce testcases"));
51193323Sed
52234353Sdim  Function* globalInitUsesExternalBA(GlobalVariable* GV) {
53234353Sdim    if (!GV->hasInitializer())
54276479Sdim      return nullptr;
55234353Sdim
56234353Sdim    Constant *I = GV->getInitializer();
57234353Sdim
58234353Sdim    // walk the values used by the initializer
59234353Sdim    // (and recurse into things like ConstantExpr)
60234353Sdim    std::vector<Constant*> Todo;
61234353Sdim    std::set<Constant*> Done;
62234353Sdim    Todo.push_back(I);
63234353Sdim
64234353Sdim    while (!Todo.empty()) {
65234353Sdim      Constant* V = Todo.back();
66234353Sdim      Todo.pop_back();
67234353Sdim      Done.insert(V);
68234353Sdim
69234353Sdim      if (BlockAddress *BA = dyn_cast<BlockAddress>(V)) {
70234353Sdim        Function *F = BA->getFunction();
71234353Sdim        if (F->isDeclaration())
72234353Sdim          return F;
73234353Sdim      }
74234353Sdim
75234353Sdim      for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) {
76234353Sdim        Constant *C = dyn_cast<Constant>(*i);
77234353Sdim        if (C && !isa<GlobalValue>(C) && !Done.count(C))
78234353Sdim          Todo.push_back(C);
79234353Sdim      }
80234353Sdim    }
81276479Sdim    return nullptr;
82234353Sdim  }
83234353Sdim}  // end anonymous namespace
84234353Sdim
85280031Sdimstd::unique_ptr<Module>
86280031SdimBugDriver::deleteInstructionFromProgram(const Instruction *I,
87280031Sdim                                        unsigned Simplification) {
88212793Sdim  // FIXME, use vmap?
89296417Sdim  Module *Clone = CloneModule(Program).release();
90193323Sed
91193323Sed  const BasicBlock *PBB = I->getParent();
92193323Sed  const Function *PF = PBB->getParent();
93193323Sed
94212793Sdim  Module::iterator RFI = Clone->begin(); // Get iterator to corresponding fn
95193323Sed  std::advance(RFI, std::distance(PF->getParent()->begin(),
96193323Sed                                  Module::const_iterator(PF)));
97193323Sed
98193323Sed  Function::iterator RBI = RFI->begin();  // Get iterator to corresponding BB
99193323Sed  std::advance(RBI, std::distance(PF->begin(), Function::const_iterator(PBB)));
100193323Sed
101193323Sed  BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst
102193323Sed  std::advance(RI, std::distance(PBB->begin(), BasicBlock::const_iterator(I)));
103296417Sdim  Instruction *TheInst = &*RI; // Got the corresponding instruction!
104193323Sed
105193323Sed  // If this instruction produces a value, replace any users with null values
106210006Srdivacky  if (!TheInst->getType()->isVoidTy())
107193323Sed    TheInst->replaceAllUsesWith(Constant::getNullValue(TheInst->getType()));
108193323Sed
109193323Sed  // Remove the instruction from the program.
110193323Sed  TheInst->getParent()->getInstList().erase(TheInst);
111193323Sed
112193323Sed  // Spiff up the output a little bit.
113212793Sdim  std::vector<std::string> Passes;
114193323Sed
115212793Sdim  /// Can we get rid of the -disable-* options?
116193323Sed  if (Simplification > 1 && !NoDCE)
117212793Sdim    Passes.push_back("dce");
118193323Sed  if (Simplification && !DisableSimplifyCFG)
119212793Sdim    Passes.push_back("simplifycfg");      // Delete dead control flow
120193323Sed
121212793Sdim  Passes.push_back("verify");
122280031Sdim  std::unique_ptr<Module> New = runPassesOn(Clone, Passes);
123212793Sdim  delete Clone;
124212793Sdim  if (!New) {
125212793Sdim    errs() << "Instruction removal failed.  Sorry. :(  Please report a bug!\n";
126212793Sdim    exit(1);
127212793Sdim  }
128212793Sdim  return New;
129193323Sed}
130193323Sed
131280031Sdimstd::unique_ptr<Module>
132280031SdimBugDriver::performFinalCleanups(Module *M, bool MayModifySemantics) {
133193323Sed  // Make all functions external, so GlobalDCE doesn't delete them...
134193323Sed  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
135193323Sed    I->setLinkage(GlobalValue::ExternalLinkage);
136193323Sed
137212793Sdim  std::vector<std::string> CleanupPasses;
138212793Sdim  CleanupPasses.push_back("globaldce");
139193323Sed
140193323Sed  if (MayModifySemantics)
141212793Sdim    CleanupPasses.push_back("deadarghaX0r");
142193323Sed  else
143212793Sdim    CleanupPasses.push_back("deadargelim");
144193323Sed
145280031Sdim  std::unique_ptr<Module> New = runPassesOn(M, CleanupPasses);
146276479Sdim  if (!New) {
147198090Srdivacky    errs() << "Final cleanups failed.  Sorry. :(  Please report a bug!\n";
148280031Sdim    return nullptr;
149193323Sed  }
150193323Sed  delete M;
151193323Sed  return New;
152193323Sed}
153193323Sed
154280031Sdimstd::unique_ptr<Module> BugDriver::extractLoop(Module *M) {
155212793Sdim  std::vector<std::string> LoopExtractPasses;
156212793Sdim  LoopExtractPasses.push_back("loop-extract-single");
157193323Sed
158280031Sdim  std::unique_ptr<Module> NewM = runPassesOn(M, LoopExtractPasses);
159276479Sdim  if (!NewM) {
160198090Srdivacky    outs() << "*** Loop extraction failed: ";
161212793Sdim    EmitProgressBitcode(M, "loopextraction", true);
162198090Srdivacky    outs() << "*** Sorry. :(  Please report a bug!\n";
163276479Sdim    return nullptr;
164193323Sed  }
165193323Sed
166193323Sed  // Check to see if we created any new functions.  If not, no loops were
167193323Sed  // extracted and we should return null.  Limit the number of loops we extract
168193323Sed  // to avoid taking forever.
169193323Sed  static unsigned NumExtracted = 32;
170193323Sed  if (M->size() == NewM->size() || --NumExtracted == 0) {
171276479Sdim    return nullptr;
172193323Sed  } else {
173193323Sed    assert(M->size() < NewM->size() && "Loop extract removed functions?");
174193323Sed    Module::iterator MI = NewM->begin();
175193323Sed    for (unsigned i = 0, e = M->size(); i != e; ++i)
176193323Sed      ++MI;
177193323Sed  }
178193323Sed
179193323Sed  return NewM;
180193323Sed}
181193323Sed
182296417Sdimstatic void eliminateAliases(GlobalValue *GV) {
183296417Sdim  // First, check whether a GlobalAlias references this definition.
184296417Sdim  // GlobalAlias MAY NOT reference declarations.
185296417Sdim  for (;;) {
186296417Sdim    // 1. Find aliases
187296417Sdim    SmallVector<GlobalAlias*,1> aliases;
188296417Sdim    Module *M = GV->getParent();
189296417Sdim    for (Module::alias_iterator I=M->alias_begin(), E=M->alias_end(); I!=E; ++I)
190296417Sdim      if (I->getAliasee()->stripPointerCasts() == GV)
191296417Sdim        aliases.push_back(&*I);
192296417Sdim    if (aliases.empty())
193296417Sdim      break;
194296417Sdim    // 2. Resolve aliases
195296417Sdim    for (unsigned i=0, e=aliases.size(); i<e; ++i) {
196296417Sdim      aliases[i]->replaceAllUsesWith(aliases[i]->getAliasee());
197296417Sdim      aliases[i]->eraseFromParent();
198296417Sdim    }
199296417Sdim    // 3. Repeat until no more aliases found; there might
200296417Sdim    // be an alias to an alias...
201296417Sdim  }
202296417Sdim}
203193323Sed
204296417Sdim//
205296417Sdim// DeleteGlobalInitializer - "Remove" the global variable by deleting its initializer,
206296417Sdim// making it external.
207296417Sdim//
208296417Sdimvoid llvm::DeleteGlobalInitializer(GlobalVariable *GV) {
209296417Sdim  eliminateAliases(GV);
210296417Sdim  GV->setInitializer(nullptr);
211296417Sdim}
212296417Sdim
213193323Sed// DeleteFunctionBody - "Remove" the function by deleting all of its basic
214193323Sed// blocks, making it external.
215193323Sed//
216193323Sedvoid llvm::DeleteFunctionBody(Function *F) {
217296417Sdim  eliminateAliases(F);
218296417Sdim
219193323Sed  // delete the body of the function...
220193323Sed  F->deleteBody();
221193323Sed  assert(F->isDeclaration() && "This didn't make the function external!");
222193323Sed}
223193323Sed
224193323Sed/// GetTorInit - Given a list of entries for static ctors/dtors, return them
225193323Sed/// as a constant array.
226193323Sedstatic Constant *GetTorInit(std::vector<std::pair<Function*, int> > &TorList) {
227193323Sed  assert(!TorList.empty() && "Don't create empty tor list!");
228193323Sed  std::vector<Constant*> ArrayElts;
229224133Sdim  Type *Int32Ty = Type::getInt32Ty(TorList[0].first->getContext());
230288943Sdim
231226584Sdim  StructType *STy =
232288943Sdim      StructType::get(Int32Ty, TorList[0].first->getType(), nullptr);
233193323Sed  for (unsigned i = 0, e = TorList.size(); i != e; ++i) {
234224133Sdim    Constant *Elts[] = {
235224133Sdim      ConstantInt::get(Int32Ty, TorList[i].second),
236224133Sdim      TorList[i].first
237224133Sdim    };
238224133Sdim    ArrayElts.push_back(ConstantStruct::get(STy, Elts));
239193323Sed  }
240193323Sed  return ConstantArray::get(ArrayType::get(ArrayElts[0]->getType(),
241193323Sed                                           ArrayElts.size()),
242193323Sed                            ArrayElts);
243193323Sed}
244193323Sed
245193323Sed/// SplitStaticCtorDtor - A module was recently split into two parts, M1/M2, and
246193323Sed/// M1 has all of the global variables.  If M2 contains any functions that are
247193323Sed/// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and
248193323Sed/// prune appropriate entries out of M1s list.
249193323Sedstatic void SplitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2,
250218885Sdim                                ValueToValueMapTy &VMap) {
251193323Sed  GlobalVariable *GV = M1->getNamedGlobal(GlobalName);
252193323Sed  if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() ||
253193323Sed      !GV->use_empty()) return;
254193323Sed
255193323Sed  std::vector<std::pair<Function*, int> > M1Tors, M2Tors;
256193323Sed  ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
257193323Sed  if (!InitList) return;
258193323Sed
259193323Sed  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
260193323Sed    if (ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i))){
261193323Sed      if (CS->getNumOperands() != 2) return;  // Not array of 2-element structs.
262193323Sed
263193323Sed      if (CS->getOperand(1)->isNullValue())
264193323Sed        break;  // Found a null terminator, stop here.
265193323Sed
266193323Sed      ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
267193323Sed      int Priority = CI ? CI->getSExtValue() : 0;
268193323Sed
269193323Sed      Constant *FP = CS->getOperand(1);
270193323Sed      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
271193323Sed        if (CE->isCast())
272193323Sed          FP = CE->getOperand(0);
273193323Sed      if (Function *F = dyn_cast<Function>(FP)) {
274193323Sed        if (!F->isDeclaration())
275193323Sed          M1Tors.push_back(std::make_pair(F, Priority));
276193323Sed        else {
277193323Sed          // Map to M2's version of the function.
278210006Srdivacky          F = cast<Function>(VMap[F]);
279193323Sed          M2Tors.push_back(std::make_pair(F, Priority));
280193323Sed        }
281193323Sed      }
282193323Sed    }
283193323Sed  }
284193323Sed
285193323Sed  GV->eraseFromParent();
286193323Sed  if (!M1Tors.empty()) {
287193323Sed    Constant *M1Init = GetTorInit(M1Tors);
288198090Srdivacky    new GlobalVariable(*M1, M1Init->getType(), false,
289198090Srdivacky                       GlobalValue::AppendingLinkage,
290198090Srdivacky                       M1Init, GlobalName);
291193323Sed  }
292193323Sed
293193323Sed  GV = M2->getNamedGlobal(GlobalName);
294193323Sed  assert(GV && "Not a clone of M1?");
295193323Sed  assert(GV->use_empty() && "llvm.ctors shouldn't have uses!");
296193323Sed
297193323Sed  GV->eraseFromParent();
298193323Sed  if (!M2Tors.empty()) {
299193323Sed    Constant *M2Init = GetTorInit(M2Tors);
300198090Srdivacky    new GlobalVariable(*M2, M2Init->getType(), false,
301198090Srdivacky                       GlobalValue::AppendingLinkage,
302198090Srdivacky                       M2Init, GlobalName);
303193323Sed  }
304193323Sed}
305193323Sed
306296417Sdimstd::unique_ptr<Module>
307296417Sdimllvm::SplitFunctionsOutOfModule(Module *M, const std::vector<Function *> &F,
308218885Sdim                                ValueToValueMapTy &VMap) {
309193323Sed  // Make sure functions & globals are all external so that linkage
310193323Sed  // between the two modules will work.
311193323Sed  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
312193323Sed    I->setLinkage(GlobalValue::ExternalLinkage);
313193323Sed  for (Module::global_iterator I = M->global_begin(), E = M->global_end();
314193323Sed       I != E; ++I) {
315198090Srdivacky    if (I->hasName() && I->getName()[0] == '\01')
316198090Srdivacky      I->setName(I->getName().substr(1));
317193323Sed    I->setLinkage(GlobalValue::ExternalLinkage);
318193323Sed  }
319193323Sed
320218885Sdim  ValueToValueMapTy NewVMap;
321296417Sdim  std::unique_ptr<Module> New = CloneModule(M, NewVMap);
322193323Sed
323193323Sed  // Remove the Test functions from the Safe module
324193323Sed  std::set<Function *> TestFunctions;
325193323Sed  for (unsigned i = 0, e = F.size(); i != e; ++i) {
326210006Srdivacky    Function *TNOF = cast<Function>(VMap[F[i]]);
327198090Srdivacky    DEBUG(errs() << "Removing function ");
328276479Sdim    DEBUG(TNOF->printAsOperand(errs(), false));
329198090Srdivacky    DEBUG(errs() << "\n");
330210006Srdivacky    TestFunctions.insert(cast<Function>(NewVMap[TNOF]));
331193323Sed    DeleteFunctionBody(TNOF);       // Function is now external in this module!
332193323Sed  }
333193323Sed
334193323Sed
335193323Sed  // Remove the Safe functions from the Test module
336296417Sdim  for (Function &I : *New)
337296417Sdim    if (!TestFunctions.count(&I))
338296417Sdim      DeleteFunctionBody(&I);
339193323Sed
340234353Sdim  // Try to split the global initializers evenly
341296417Sdim  for (GlobalVariable &I : M->globals()) {
342296417Sdim    GlobalVariable *GV = cast<GlobalVariable>(NewVMap[&I]);
343296417Sdim    if (Function *TestFn = globalInitUsesExternalBA(&I)) {
344234353Sdim      if (Function *SafeFn = globalInitUsesExternalBA(GV)) {
345234353Sdim        errs() << "*** Error: when reducing functions, encountered "
346234353Sdim                  "the global '";
347276479Sdim        GV->printAsOperand(errs(), false);
348234353Sdim        errs() << "' with an initializer that references blockaddresses "
349234353Sdim                  "from safe function '" << SafeFn->getName()
350234353Sdim               << "' and from test function '" << TestFn->getName() << "'.\n";
351234353Sdim        exit(1);
352234353Sdim      }
353296417Sdim      DeleteGlobalInitializer(&I); // Delete the initializer to make it external
354234353Sdim    } else {
355234353Sdim      // If we keep it in the safe module, then delete it in the test module
356296417Sdim      DeleteGlobalInitializer(GV);
357234353Sdim    }
358234353Sdim  }
359234353Sdim
360193323Sed  // Make sure that there is a global ctor/dtor array in both halves of the
361193323Sed  // module if they both have static ctor/dtor functions.
362296417Sdim  SplitStaticCtorDtor("llvm.global_ctors", M, New.get(), NewVMap);
363296417Sdim  SplitStaticCtorDtor("llvm.global_dtors", M, New.get(), NewVMap);
364296417Sdim
365193323Sed  return New;
366193323Sed}
367193323Sed
368193323Sed//===----------------------------------------------------------------------===//
369193323Sed// Basic Block Extraction Code
370193323Sed//===----------------------------------------------------------------------===//
371193323Sed
372280031Sdimstd::unique_ptr<Module>
373280031SdimBugDriver::extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs,
374280031Sdim                                         Module *M) {
375261991Sdim  SmallString<128> Filename;
376261991Sdim  int FD;
377276479Sdim  std::error_code EC = sys::fs::createUniqueFile(
378261991Sdim      OutputPrefix + "-extractblocks%%%%%%%", FD, Filename);
379261991Sdim  if (EC) {
380198090Srdivacky    outs() << "*** Basic Block extraction failed!\n";
381261991Sdim    errs() << "Error creating temporary file: " << EC.message() << "\n";
382212793Sdim    EmitProgressBitcode(M, "basicblockextractfail", true);
383276479Sdim    return nullptr;
384193323Sed  }
385261991Sdim  sys::RemoveFileOnSignal(Filename);
386193323Sed
387261991Sdim  tool_output_file BlocksToNotExtractFile(Filename.c_str(), FD);
388193323Sed  for (std::vector<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end();
389193323Sed       I != E; ++I) {
390193323Sed    BasicBlock *BB = *I;
391193323Sed    // If the BB doesn't have a name, give it one so we have something to key
392193323Sed    // off of.
393193323Sed    if (!BB->hasName()) BB->setName("tmpbb");
394234353Sdim    BlocksToNotExtractFile.os() << BB->getParent()->getName() << " "
395212793Sdim                                << BB->getName() << "\n";
396193323Sed  }
397212793Sdim  BlocksToNotExtractFile.os().close();
398212793Sdim  if (BlocksToNotExtractFile.os().has_error()) {
399261991Sdim    errs() << "Error writing list of blocks to not extract\n";
400212793Sdim    EmitProgressBitcode(M, "basicblockextractfail", true);
401212793Sdim    BlocksToNotExtractFile.os().clear_error();
402276479Sdim    return nullptr;
403212793Sdim  }
404212793Sdim  BlocksToNotExtractFile.keep();
405193323Sed
406261991Sdim  std::string uniqueFN = "--extract-blocks-file=";
407261991Sdim  uniqueFN += Filename.str();
408203954Srdivacky  const char *ExtraArg = uniqueFN.c_str();
409193323Sed
410212793Sdim  std::vector<std::string> PI;
411212793Sdim  PI.push_back("extract-blocks");
412280031Sdim  std::unique_ptr<Module> Ret = runPassesOn(M, PI, false, 1, &ExtraArg);
413193323Sed
414261991Sdim  sys::fs::remove(Filename.c_str());
415193323Sed
416276479Sdim  if (!Ret) {
417198090Srdivacky    outs() << "*** Basic Block extraction failed, please report a bug!\n";
418212793Sdim    EmitProgressBitcode(M, "basicblockextractfail", true);
419193323Sed  }
420193323Sed  return Ret;
421193323Sed}
422