//===- ExtractFunction.cpp - Extract a function from Program --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements several methods that are used to extract functions,
// loops, or portions of a module from the rest of the module.
//
//===----------------------------------------------------------------------===//

#include "BugDriver.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/CodeExtractor.h"
#include <set>
using namespace llvm;

#define DEBUG_TYPE "bugpoint"

bool llvm::DisableSimplifyCFG = false;

static cl::opt<bool>
    NoDCE("disable-dce",
          cl::desc("Do not use the -dce pass to reduce testcases"));
static cl::opt<bool, true>
    NoSCFG("disable-simplifycfg", cl::location(DisableSimplifyCFG),
           cl::desc("Do not use the -simplifycfg pass to reduce testcases"));

static Function *globalInitUsesExternalBA(GlobalVariable *GV) {
  if (!GV->hasInitializer())
    return nullptr;

  Constant *I = GV->getInitializer();

  // walk the values used by the initializer
  // (and recurse into things like ConstantExpr)
  std::vector<Constant *> Todo;
  std::set<Constant *> Done;
  Todo.push_back(I);

  while (!Todo.empty()) {
    Constant *V = Todo.back();
    Todo.pop_back();
    Done.insert(V);

    if (BlockAddress *BA = dyn_cast<BlockAddress>(V)) {
      Function *F = BA->getFunction();
      if (F->isDeclaration())
        return F;
    }

    for (User::op_iterator i = V->op_begin(), e = V->op_end(); i != e; ++i) {
      Constant *C = dyn_cast<Constant>(*i);
      if (C && !isa<GlobalValue>(C) && !Done.count(C))
        Todo.push_back(C);
    }
  }
  return nullptr;
}

std::unique_ptr<Module>
BugDriver::deleteInstructionFromProgram(const Instruction *I,
                                        unsigned Simplification) {
  // FIXME, use vmap?
  std::unique_ptr<Module> Clone = CloneModule(*Program);

  const BasicBlock *PBB = I->getParent();
  const Function *PF = PBB->getParent();

  Module::iterator RFI = Clone->begin(); // Get iterator to corresponding fn
  std::advance(
      RFI, std::distance(PF->getParent()->begin(), Module::const_iterator(PF)));

  Function::iterator RBI = RFI->begin(); // Get iterator to corresponding BB
  std::advance(RBI, std::distance(PF->begin(), Function::const_iterator(PBB)));

  BasicBlock::iterator RI = RBI->begin(); // Get iterator to corresponding inst
  std::advance(RI, std::distance(PBB->begin(), BasicBlock::const_iterator(I)));
  Instruction *TheInst = &*RI; // Got the corresponding instruction!

  // If this instruction produces a value, replace any users with null values
  if (!TheInst->getType()->isVoidTy())
    TheInst->replaceAllUsesWith(Constant::getNullValue(TheInst->getType()));

  // Remove the instruction from the program.
  TheInst->eraseFromParent();

  // Spiff up the output a little bit.
  std::vector<std::string> Passes;

  /// Can we get rid of the -disable-* options?
  if (Simplification > 1 && !NoDCE)
    Passes.push_back("dce");
  if (Simplification && !DisableSimplifyCFG)
    Passes.push_back("simplifycfg"); // Delete dead control flow

  Passes.push_back("verify");
  std::unique_ptr<Module> New = runPassesOn(Clone.get(), Passes);
  if (!New) {
    errs() << "Instruction removal failed.  Sorry. :(  Please report a bug!\n";
    exit(1);
  }
  return New;
}

std::unique_ptr<Module>
BugDriver::performFinalCleanups(std::unique_ptr<Module> M,
                                bool MayModifySemantics) {
  // Make all functions external, so GlobalDCE doesn't delete them...
  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
    I->setLinkage(GlobalValue::ExternalLinkage);

  std::vector<std::string> CleanupPasses;

  if (MayModifySemantics)
    CleanupPasses.push_back("deadarghaX0r");
  else
    CleanupPasses.push_back("deadargelim");

  std::unique_ptr<Module> New = runPassesOn(M.get(), CleanupPasses);
  if (!New) {
    errs() << "Final cleanups failed.  Sorry. :(  Please report a bug!\n";
    return nullptr;
  }
  return New;
}

std::unique_ptr<Module> BugDriver::extractLoop(Module *M) {
  std::vector<std::string> LoopExtractPasses;
  LoopExtractPasses.push_back("loop-extract-single");

  std::unique_ptr<Module> NewM = runPassesOn(M, LoopExtractPasses);
  if (!NewM) {
    outs() << "*** Loop extraction failed: ";
    emitProgressBitcode(*M, "loopextraction", true);
    outs() << "*** Sorry. :(  Please report a bug!\n";
    return nullptr;
  }

  // Check to see if we created any new functions.  If not, no loops were
  // extracted and we should return null.  Limit the number of loops we extract
  // to avoid taking forever.
  static unsigned NumExtracted = 32;
  if (M->size() == NewM->size() || --NumExtracted == 0) {
    return nullptr;
  } else {
    assert(M->size() < NewM->size() && "Loop extract removed functions?");
    Module::iterator MI = NewM->begin();
    for (unsigned i = 0, e = M->size(); i != e; ++i)
      ++MI;
  }

  return NewM;
}

static void eliminateAliases(GlobalValue *GV) {
  // First, check whether a GlobalAlias references this definition.
  // GlobalAlias MAY NOT reference declarations.
  for (;;) {
    // 1. Find aliases
    SmallVector<GlobalAlias *, 1> aliases;
    Module *M = GV->getParent();
    for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end();
         I != E; ++I)
      if (I->getAliasee()->stripPointerCasts() == GV)
        aliases.push_back(&*I);
    if (aliases.empty())
      break;
    // 2. Resolve aliases
    for (unsigned i = 0, e = aliases.size(); i < e; ++i) {
      aliases[i]->replaceAllUsesWith(aliases[i]->getAliasee());
      aliases[i]->eraseFromParent();
    }
    // 3. Repeat until no more aliases found; there might
    // be an alias to an alias...
  }
}

// "Remove" the global variable by deleting its initializer, making it external.
void llvm::deleteGlobalInitializer(GlobalVariable *GV) {
  eliminateAliases(GV);
  GV->setInitializer(nullptr);
  GV->setComdat(nullptr);
}

// "Remove" the function by deleting all of its basic blocks, making it
// external.
void llvm::deleteFunctionBody(Function *F) {
  eliminateAliases(F);
  // Function declarations can't have comdats.
  F->setComdat(nullptr);

  // delete the body of the function...
  F->deleteBody();
  assert(F->isDeclaration() && "This didn't make the function external!");
}

/// getTorInit - Given a list of entries for static ctors/dtors, return them
/// as a constant array.
static Constant *getTorInit(std::vector<std::pair<Function *, int>> &TorList) {
  assert(!TorList.empty() && "Don't create empty tor list!");
  std::vector<Constant *> ArrayElts;
  Type *Int32Ty = Type::getInt32Ty(TorList[0].first->getContext());

  StructType *STy = StructType::get(Int32Ty, TorList[0].first->getType());
  for (unsigned i = 0, e = TorList.size(); i != e; ++i) {
    Constant *Elts[] = {ConstantInt::get(Int32Ty, TorList[i].second),
                        TorList[i].first};
    ArrayElts.push_back(ConstantStruct::get(STy, Elts));
  }
  return ConstantArray::get(
      ArrayType::get(ArrayElts[0]->getType(), ArrayElts.size()), ArrayElts);
}

/// splitStaticCtorDtor - A module was recently split into two parts, M1/M2, and
/// M1 has all of the global variables.  If M2 contains any functions that are
/// static ctors/dtors, we need to add an llvm.global_[cd]tors global to M2, and
/// prune appropriate entries out of M1s list.
static void splitStaticCtorDtor(const char *GlobalName, Module *M1, Module *M2,
                                ValueToValueMapTy &VMap) {
  GlobalVariable *GV = M1->getNamedGlobal(GlobalName);
  if (!GV || GV->isDeclaration() || GV->hasLocalLinkage() || !GV->use_empty())
    return;

  std::vector<std::pair<Function *, int>> M1Tors, M2Tors;
  ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
  if (!InitList)
    return;

  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
    if (ConstantStruct *CS =
            dyn_cast<ConstantStruct>(InitList->getOperand(i))) {
      if (CS->getNumOperands() != 2)
        return; // Not array of 2-element structs.

      if (CS->getOperand(1)->isNullValue())
        break; // Found a null terminator, stop here.

      ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
      int Priority = CI ? CI->getSExtValue() : 0;

      Constant *FP = CS->getOperand(1);
      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(FP))
        if (CE->isCast())
          FP = CE->getOperand(0);
      if (Function *F = dyn_cast<Function>(FP)) {
        if (!F->isDeclaration())
          M1Tors.push_back(std::make_pair(F, Priority));
        else {
          // Map to M2's version of the function.
          F = cast<Function>(VMap[F]);
          M2Tors.push_back(std::make_pair(F, Priority));
        }
      }
    }
  }

  GV->eraseFromParent();
  if (!M1Tors.empty()) {
    Constant *M1Init = getTorInit(M1Tors);
    new GlobalVariable(*M1, M1Init->getType(), false,
                       GlobalValue::AppendingLinkage, M1Init, GlobalName);
  }

  GV = M2->getNamedGlobal(GlobalName);
  assert(GV && "Not a clone of M1?");
  assert(GV->use_empty() && "llvm.ctors shouldn't have uses!");

  GV->eraseFromParent();
  if (!M2Tors.empty()) {
    Constant *M2Init = getTorInit(M2Tors);
    new GlobalVariable(*M2, M2Init->getType(), false,
                       GlobalValue::AppendingLinkage, M2Init, GlobalName);
  }
}

std::unique_ptr<Module>
llvm::splitFunctionsOutOfModule(Module *M, const std::vector<Function *> &F,
                                ValueToValueMapTy &VMap) {
  // Make sure functions & globals are all external so that linkage
  // between the two modules will work.
  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
    I->setLinkage(GlobalValue::ExternalLinkage);
  for (Module::global_iterator I = M->global_begin(), E = M->global_end();
       I != E; ++I) {
    if (I->hasName() && I->getName()[0] == '\01')
      I->setName(I->getName().substr(1));
    I->setLinkage(GlobalValue::ExternalLinkage);
  }

  ValueToValueMapTy NewVMap;
  std::unique_ptr<Module> New = CloneModule(*M, NewVMap);

  // Remove the Test functions from the Safe module
  std::set<Function *> TestFunctions;
  for (unsigned i = 0, e = F.size(); i != e; ++i) {
    Function *TNOF = cast<Function>(VMap[F[i]]);
    LLVM_DEBUG(errs() << "Removing function ");
    LLVM_DEBUG(TNOF->printAsOperand(errs(), false));
    LLVM_DEBUG(errs() << "\n");
    TestFunctions.insert(cast<Function>(NewVMap[TNOF]));
    deleteFunctionBody(TNOF); // Function is now external in this module!
  }

  // Remove the Safe functions from the Test module
  for (Function &I : *New)
    if (!TestFunctions.count(&I))
      deleteFunctionBody(&I);

  // Try to split the global initializers evenly
  for (GlobalVariable &I : M->globals()) {
    GlobalVariable *GV = cast<GlobalVariable>(NewVMap[&I]);
    if (Function *TestFn = globalInitUsesExternalBA(&I)) {
      if (Function *SafeFn = globalInitUsesExternalBA(GV)) {
        errs() << "*** Error: when reducing functions, encountered "
                  "the global '";
        GV->printAsOperand(errs(), false);
        errs() << "' with an initializer that references blockaddresses "
                  "from safe function '"
               << SafeFn->getName() << "' and from test function '"
               << TestFn->getName() << "'.\n";
        exit(1);
      }
      deleteGlobalInitializer(&I); // Delete the initializer to make it external
    } else {
      // If we keep it in the safe module, then delete it in the test module
      deleteGlobalInitializer(GV);
    }
  }

  // Make sure that there is a global ctor/dtor array in both halves of the
  // module if they both have static ctor/dtor functions.
  splitStaticCtorDtor("llvm.global_ctors", M, New.get(), NewVMap);
  splitStaticCtorDtor("llvm.global_dtors", M, New.get(), NewVMap);

  return New;
}

//===----------------------------------------------------------------------===//
// Basic Block Extraction Code
//===----------------------------------------------------------------------===//

std::unique_ptr<Module>
BugDriver::extractMappedBlocksFromModule(const std::vector<BasicBlock *> &BBs,
                                         Module *M) {
  auto Temp = sys::fs::TempFile::create(OutputPrefix + "-extractblocks%%%%%%%");
  if (!Temp) {
    outs() << "*** Basic Block extraction failed!\n";
    errs() << "Error creating temporary file: " << toString(Temp.takeError())
           << "\n";
    emitProgressBitcode(*M, "basicblockextractfail", true);
    return nullptr;
  }
  DiscardTemp Discard{*Temp};

  // Extract all of the blocks except the ones in BBs.
  SmallVector<BasicBlock *, 32> BlocksToExtract;
  for (Function &F : *M)
    for (BasicBlock &BB : F)
      // Check if this block is going to be extracted.
      if (!llvm::is_contained(BBs, &BB))
        BlocksToExtract.push_back(&BB);

  raw_fd_ostream OS(Temp->FD, /*shouldClose*/ false);
  for (BasicBlock *BB : BBs) {
    // If the BB doesn't have a name, give it one so we have something to key
    // off of.
    if (!BB->hasName())
      BB->setName("tmpbb");
    OS << BB->getParent()->getName() << " " << BB->getName() << "\n";
  }
  OS.flush();
  if (OS.has_error()) {
    errs() << "Error writing list of blocks to not extract\n";
    emitProgressBitcode(*M, "basicblockextractfail", true);
    OS.clear_error();
    return nullptr;
  }

  std::string uniqueFN = "--extract-blocks-file=";
  uniqueFN += Temp->TmpName;

  std::vector<std::string> PI;
  PI.push_back("extract-blocks");
  std::unique_ptr<Module> Ret = runPassesOn(M, PI, {uniqueFN});

  if (!Ret) {
    outs() << "*** Basic Block extraction failed, please report a bug!\n";
    emitProgressBitcode(*M, "basicblockextractfail", true);
  }
  return Ret;
}
