//===-- llvm-stress.cpp - Generate random LL files to stress-test LLVM ----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This program is a utility that generates random .ll files to stress-test
// different components in LLVM.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/LegacyPassNameParser.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/ToolOutputFile.h"
#include <algorithm>
#include <vector>

namespace llvm {

static cl::opt<unsigned> SeedCL("seed",
  cl::desc("Seed used for randomness"), cl::init(0));
static cl::opt<unsigned> SizeCL("size",
  cl::desc("The estimated size of the generated function (# of instrs)"),
  cl::init(100));
static cl::opt<std::string>
OutputFilename("o", cl::desc("Override output filename"),
               cl::value_desc("filename"));

static LLVMContext Context;

namespace cl {
template <> class parser<Type*> final : public basic_parser<Type*> {
public:
  parser(Option &O) : basic_parser(O) {}

  // Parse options as IR types. Return true on error.
  bool parse(Option &O, StringRef, StringRef Arg, Type *&Value) {
    if      (Arg == "half")      Value = Type::getHalfTy(Context);
    else if (Arg == "fp128")     Value = Type::getFP128Ty(Context);
    else if (Arg == "x86_fp80")  Value = Type::getX86_FP80Ty(Context);
    else if (Arg == "ppc_fp128") Value = Type::getPPC_FP128Ty(Context);
    else if (Arg == "x86_mmx")   Value = Type::getX86_MMXTy(Context);
    else if (Arg.startswith("i")) {
      unsigned N = 0;
      Arg.drop_front().getAsInteger(10, N);
      if (N > 0)
        Value = Type::getIntNTy(Context, N);
    }

    if (!Value)
      return O.error("Invalid IR scalar type: '" + Arg + "'!");
    return false;
  }

  StringRef getValueName() const override { return "IR scalar type"; }
};
}


static cl::list<Type*> AdditionalScalarTypes("types", cl::CommaSeparated,
  cl::desc("Additional IR scalar types "
           "(always includes i1, i8, i16, i32, i64, float and double)"));

namespace {
/// A utility class to provide a pseudo-random number generator which is
/// the same across all platforms. This is somewhat close to the libc
/// implementation. Note: This is not a cryptographically secure pseudorandom
/// number generator.
class Random {
public:
  /// C'tor
  Random(unsigned _seed):Seed(_seed) {}

  /// Return a random integer, up to a
  /// maximum of 2**19 - 1.
  uint32_t Rand() {
    uint32_t Val = Seed + 0x000b07a1;
    Seed = (Val * 0x3c7c0ac1);
    // Only lowest 19 bits are random-ish.
    return Seed & 0x7ffff;
  }

  /// Return a random 32 bit integer.
  uint32_t Rand32() {
    uint32_t Val = Rand();
    Val &= 0xffff;
    return Val | (Rand() << 16);
  }

  /// Return a random 64 bit integer.
  uint64_t Rand64() {
    uint64_t Val = Rand32();
    return Val | (uint64_t(Rand32()) << 32);
  }

  /// Rand operator for STL algorithms.
  ptrdiff_t operator()(ptrdiff_t y) {
    return  Rand64() % y;
  }

private:
  unsigned Seed;
};

/// Generate an empty function with a default argument list.
Function *GenEmptyFunction(Module *M) {
  // Define a few arguments
  LLVMContext &Context = M->getContext();
  Type* ArgsTy[] = {
    Type::getInt8PtrTy(Context),
    Type::getInt32PtrTy(Context),
    Type::getInt64PtrTy(Context),
    Type::getInt32Ty(Context),
    Type::getInt64Ty(Context),
    Type::getInt8Ty(Context)
  };

  auto *FuncTy = FunctionType::get(Type::getVoidTy(Context), ArgsTy, false);
  // Pick a unique name to describe the input parameters
  Twine Name = "autogen_SD" + Twine{SeedCL};
  auto *Func = Function::Create(FuncTy, GlobalValue::ExternalLinkage, Name, M);
  Func->setCallingConv(CallingConv::C);
  return Func;
}

/// A base class, implementing utilities needed for
/// modifying and adding new random instructions.
struct Modifier {
  /// Used to store the randomly generated values.
  typedef std::vector<Value*> PieceTable;

public:
  /// C'tor
  Modifier(BasicBlock *Block, PieceTable *PT, Random *R):
    BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {}

  /// virtual D'tor to silence warnings.
  virtual ~Modifier() {}

  /// Add a new instruction.
  virtual void Act() = 0;
  /// Add N new instructions,
  virtual void ActN(unsigned n) {
    for (unsigned i=0; i<n; ++i)
      Act();
  }

protected:
  /// Return a random value from the list of known values.
  Value *getRandomVal() {
    assert(PT->size());
    return PT->at(Ran->Rand() % PT->size());
  }

  Constant *getRandomConstant(Type *Tp) {
    if (Tp->isIntegerTy()) {
      if (Ran->Rand() & 1)
        return ConstantInt::getAllOnesValue(Tp);
      return ConstantInt::getNullValue(Tp);
    } else if (Tp->isFloatingPointTy()) {
      if (Ran->Rand() & 1)
        return ConstantFP::getAllOnesValue(Tp);
      return ConstantFP::getNullValue(Tp);
    }
    return UndefValue::get(Tp);
  }

  /// Return a random value with a known type.
  Value *getRandomValue(Type *Tp) {
    unsigned index = Ran->Rand();
    for (unsigned i=0; i<PT->size(); ++i) {
      Value *V = PT->at((index + i) % PT->size());
      if (V->getType() == Tp)
        return V;
    }

    // If the requested type was not found, generate a constant value.
    if (Tp->isIntegerTy()) {
      if (Ran->Rand() & 1)
        return ConstantInt::getAllOnesValue(Tp);
      return ConstantInt::getNullValue(Tp);
    } else if (Tp->isFloatingPointTy()) {
      if (Ran->Rand() & 1)
        return ConstantFP::getAllOnesValue(Tp);
      return ConstantFP::getNullValue(Tp);
    } else if (Tp->isVectorTy()) {
      VectorType *VTp = cast<VectorType>(Tp);

      std::vector<Constant*> TempValues;
      TempValues.reserve(VTp->getNumElements());
      for (unsigned i = 0; i < VTp->getNumElements(); ++i)
        TempValues.push_back(getRandomConstant(VTp->getScalarType()));

      ArrayRef<Constant*> VectorValue(TempValues);
      return ConstantVector::get(VectorValue);
    }

    return UndefValue::get(Tp);
  }

  /// Return a random value of any pointer type.
  Value *getRandomPointerValue() {
    unsigned index = Ran->Rand();
    for (unsigned i=0; i<PT->size(); ++i) {
      Value *V = PT->at((index + i) % PT->size());
      if (V->getType()->isPointerTy())
        return V;
    }
    return UndefValue::get(pickPointerType());
  }

  /// Return a random value of any vector type.
  Value *getRandomVectorValue() {
    unsigned index = Ran->Rand();
    for (unsigned i=0; i<PT->size(); ++i) {
      Value *V = PT->at((index + i) % PT->size());
      if (V->getType()->isVectorTy())
        return V;
    }
    return UndefValue::get(pickVectorType());
  }

  /// Pick a random type.
  Type *pickType() {
    return (Ran->Rand() & 1 ? pickVectorType() : pickScalarType());
  }

  /// Pick a random pointer type.
  Type *pickPointerType() {
    Type *Ty = pickType();
    return PointerType::get(Ty, 0);
  }

  /// Pick a random vector type.
  Type *pickVectorType(unsigned len = (unsigned)-1) {
    // Pick a random vector width in the range 2**0 to 2**4.
    // by adding two randoms we are generating a normal-like distribution
    // around 2**3.
    unsigned width = 1<<((Ran->Rand() % 3) + (Ran->Rand() % 3));
    Type *Ty;

    // Vectors of x86mmx are illegal; keep trying till we get something else.
    do {
      Ty = pickScalarType();
    } while (Ty->isX86_MMXTy());

    if (len != (unsigned)-1)
      width = len;
    return VectorType::get(Ty, width);
  }

  /// Pick a random scalar type.
  Type *pickScalarType() {
    static std::vector<Type*> ScalarTypes;
    if (ScalarTypes.empty()) {
      ScalarTypes.assign({
        Type::getInt1Ty(Context),
        Type::getInt8Ty(Context),
        Type::getInt16Ty(Context),
        Type::getInt32Ty(Context),
        Type::getInt64Ty(Context),
        Type::getFloatTy(Context),
        Type::getDoubleTy(Context)
      });
      ScalarTypes.insert(ScalarTypes.end(),
        AdditionalScalarTypes.begin(), AdditionalScalarTypes.end());
    }

    return ScalarTypes[Ran->Rand() % ScalarTypes.size()];
  }

  /// Basic block to populate
  BasicBlock *BB;
  /// Value table
  PieceTable *PT;
  /// Random number generator
  Random *Ran;
  /// Context
  LLVMContext &Context;
};

struct LoadModifier: public Modifier {
  LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
  void Act() override {
    // Try to use predefined pointers. If non-exist, use undef pointer value;
    Value *Ptr = getRandomPointerValue();
    Value *V = new LoadInst(Ptr, "L", BB->getTerminator());
    PT->push_back(V);
  }
};

struct StoreModifier: public Modifier {
  StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
  void Act() override {
    // Try to use predefined pointers. If non-exist, use undef pointer value;
    Value *Ptr = getRandomPointerValue();
    Type  *Tp = Ptr->getType();
    Value *Val = getRandomValue(Tp->getContainedType(0));
    Type  *ValTy = Val->getType();

    // Do not store vectors of i1s because they are unsupported
    // by the codegen.
    if (ValTy->isVectorTy() && ValTy->getScalarSizeInBits() == 1)
      return;

    new StoreInst(Val, Ptr, BB->getTerminator());
  }
};

struct BinModifier: public Modifier {
  BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}

  void Act() override {
    Value *Val0 = getRandomVal();
    Value *Val1 = getRandomValue(Val0->getType());

    // Don't handle pointer types.
    if (Val0->getType()->isPointerTy() ||
        Val1->getType()->isPointerTy())
      return;

    // Don't handle i1 types.
    if (Val0->getType()->getScalarSizeInBits() == 1)
      return;


    bool isFloat = Val0->getType()->getScalarType()->isFloatingPointTy();
    Instruction* Term = BB->getTerminator();
    unsigned R = Ran->Rand() % (isFloat ? 7 : 13);
    Instruction::BinaryOps Op;

    switch (R) {
    default: llvm_unreachable("Invalid BinOp");
    case 0:{Op = (isFloat?Instruction::FAdd : Instruction::Add); break; }
    case 1:{Op = (isFloat?Instruction::FSub : Instruction::Sub); break; }
    case 2:{Op = (isFloat?Instruction::FMul : Instruction::Mul); break; }
    case 3:{Op = (isFloat?Instruction::FDiv : Instruction::SDiv); break; }
    case 4:{Op = (isFloat?Instruction::FDiv : Instruction::UDiv); break; }
    case 5:{Op = (isFloat?Instruction::FRem : Instruction::SRem); break; }
    case 6:{Op = (isFloat?Instruction::FRem : Instruction::URem); break; }
    case 7: {Op = Instruction::Shl;  break; }
    case 8: {Op = Instruction::LShr; break; }
    case 9: {Op = Instruction::AShr; break; }
    case 10:{Op = Instruction::And;  break; }
    case 11:{Op = Instruction::Or;   break; }
    case 12:{Op = Instruction::Xor;  break; }
    }

    PT->push_back(BinaryOperator::Create(Op, Val0, Val1, "B", Term));
  }
};

/// Generate constant values.
struct ConstModifier: public Modifier {
  ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
  void Act() override {
    Type *Ty = pickType();

    if (Ty->isVectorTy()) {
      switch (Ran->Rand() % 2) {
      case 0: if (Ty->getScalarType()->isIntegerTy())
                return PT->push_back(ConstantVector::getAllOnesValue(Ty));
      case 1: if (Ty->getScalarType()->isIntegerTy())
                return PT->push_back(ConstantVector::getNullValue(Ty));
      }
    }

    if (Ty->isFloatingPointTy()) {
      // Generate 128 random bits, the size of the (currently)
      // largest floating-point types.
      uint64_t RandomBits[2];
      for (unsigned i = 0; i < 2; ++i)
        RandomBits[i] = Ran->Rand64();

      APInt RandomInt(Ty->getPrimitiveSizeInBits(), makeArrayRef(RandomBits));
      APFloat RandomFloat(Ty->getFltSemantics(), RandomInt);

      if (Ran->Rand() & 1)
        return PT->push_back(ConstantFP::getNullValue(Ty));
      return PT->push_back(ConstantFP::get(Ty->getContext(), RandomFloat));
    }

    if (Ty->isIntegerTy()) {
      switch (Ran->Rand() % 7) {
      case 0: if (Ty->isIntegerTy())
                return PT->push_back(ConstantInt::get(Ty,
                  APInt::getAllOnesValue(Ty->getPrimitiveSizeInBits())));
      case 1: if (Ty->isIntegerTy())
                return PT->push_back(ConstantInt::get(Ty,
                  APInt::getNullValue(Ty->getPrimitiveSizeInBits())));
      case 2: case 3: case 4: case 5:
      case 6: if (Ty->isIntegerTy())
                PT->push_back(ConstantInt::get(Ty, Ran->Rand()));
      }
    }

  }
};

struct AllocaModifier: public Modifier {
  AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){}

  void Act() override {
    Type *Tp = pickType();
    PT->push_back(new AllocaInst(Tp, "A", BB->getFirstNonPHI()));
  }
};

struct ExtractElementModifier: public Modifier {
  ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R):
    Modifier(BB, PT, R) {}

  void Act() override {
    Value *Val0 = getRandomVectorValue();
    Value *V = ExtractElementInst::Create(Val0,
             ConstantInt::get(Type::getInt32Ty(BB->getContext()),
             Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()),
             "E", BB->getTerminator());
    return PT->push_back(V);
  }
};

struct ShuffModifier: public Modifier {
  ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
  void Act() override {

    Value *Val0 = getRandomVectorValue();
    Value *Val1 = getRandomValue(Val0->getType());

    unsigned Width = cast<VectorType>(Val0->getType())->getNumElements();
    std::vector<Constant*> Idxs;

    Type *I32 = Type::getInt32Ty(BB->getContext());
    for (unsigned i=0; i<Width; ++i) {
      Constant *CI = ConstantInt::get(I32, Ran->Rand() % (Width*2));
      // Pick some undef values.
      if (!(Ran->Rand() % 5))
        CI = UndefValue::get(I32);
      Idxs.push_back(CI);
    }

    Constant *Mask = ConstantVector::get(Idxs);

    Value *V = new ShuffleVectorInst(Val0, Val1, Mask, "Shuff",
                                     BB->getTerminator());
    PT->push_back(V);
  }
};

struct InsertElementModifier: public Modifier {
  InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R):
    Modifier(BB, PT, R) {}

  void Act() override {
    Value *Val0 = getRandomVectorValue();
    Value *Val1 = getRandomValue(Val0->getType()->getScalarType());

    Value *V = InsertElementInst::Create(Val0, Val1,
              ConstantInt::get(Type::getInt32Ty(BB->getContext()),
              Ran->Rand() % cast<VectorType>(Val0->getType())->getNumElements()),
              "I",  BB->getTerminator());
    return PT->push_back(V);
  }

};

struct CastModifier: public Modifier {
  CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
  void Act() override {

    Value *V = getRandomVal();
    Type *VTy = V->getType();
    Type *DestTy = pickScalarType();

    // Handle vector casts vectors.
    if (VTy->isVectorTy()) {
      VectorType *VecTy = cast<VectorType>(VTy);
      DestTy = pickVectorType(VecTy->getNumElements());
    }

    // no need to cast.
    if (VTy == DestTy) return;

    // Pointers:
    if (VTy->isPointerTy()) {
      if (!DestTy->isPointerTy())
        DestTy = PointerType::get(DestTy, 0);
      return PT->push_back(
        new BitCastInst(V, DestTy, "PC", BB->getTerminator()));
    }

    unsigned VSize = VTy->getScalarType()->getPrimitiveSizeInBits();
    unsigned DestSize = DestTy->getScalarType()->getPrimitiveSizeInBits();

    // Generate lots of bitcasts.
    if ((Ran->Rand() & 1) && VSize == DestSize) {
      return PT->push_back(
        new BitCastInst(V, DestTy, "BC", BB->getTerminator()));
    }

    // Both types are integers:
    if (VTy->getScalarType()->isIntegerTy() &&
        DestTy->getScalarType()->isIntegerTy()) {
      if (VSize > DestSize) {
        return PT->push_back(
          new TruncInst(V, DestTy, "Tr", BB->getTerminator()));
      } else {
        assert(VSize < DestSize && "Different int types with the same size?");
        if (Ran->Rand() & 1)
          return PT->push_back(
            new ZExtInst(V, DestTy, "ZE", BB->getTerminator()));
        return PT->push_back(new SExtInst(V, DestTy, "Se", BB->getTerminator()));
      }
    }

    // Fp to int.
    if (VTy->getScalarType()->isFloatingPointTy() &&
        DestTy->getScalarType()->isIntegerTy()) {
      if (Ran->Rand() & 1)
        return PT->push_back(
          new FPToSIInst(V, DestTy, "FC", BB->getTerminator()));
      return PT->push_back(new FPToUIInst(V, DestTy, "FC", BB->getTerminator()));
    }

    // Int to fp.
    if (VTy->getScalarType()->isIntegerTy() &&
        DestTy->getScalarType()->isFloatingPointTy()) {
      if (Ran->Rand() & 1)
        return PT->push_back(
          new SIToFPInst(V, DestTy, "FC", BB->getTerminator()));
      return PT->push_back(new UIToFPInst(V, DestTy, "FC", BB->getTerminator()));

    }

    // Both floats.
    if (VTy->getScalarType()->isFloatingPointTy() &&
        DestTy->getScalarType()->isFloatingPointTy()) {
      if (VSize > DestSize) {
        return PT->push_back(
          new FPTruncInst(V, DestTy, "Tr", BB->getTerminator()));
      } else if (VSize < DestSize) {
        return PT->push_back(
          new FPExtInst(V, DestTy, "ZE", BB->getTerminator()));
      }
      // If VSize == DestSize, then the two types must be fp128 and ppc_fp128,
      // for which there is no defined conversion. So do nothing.
    }
  }

};

struct SelectModifier: public Modifier {
  SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R):
    Modifier(BB, PT, R) {}

  void Act() override {
    // Try a bunch of different select configuration until a valid one is found.
      Value *Val0 = getRandomVal();
      Value *Val1 = getRandomValue(Val0->getType());

      Type *CondTy = Type::getInt1Ty(Context);

      // If the value type is a vector, and we allow vector select, then in 50%
      // of the cases generate a vector select.
      if (Val0->getType()->isVectorTy() && (Ran->Rand() % 1)) {
        unsigned NumElem = cast<VectorType>(Val0->getType())->getNumElements();
        CondTy = VectorType::get(CondTy, NumElem);
      }

      Value *Cond = getRandomValue(CondTy);
      Value *V = SelectInst::Create(Cond, Val0, Val1, "Sl", BB->getTerminator());
      return PT->push_back(V);
  }
};


struct CmpModifier: public Modifier {
  CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {}
  void Act() override {

    Value *Val0 = getRandomVal();
    Value *Val1 = getRandomValue(Val0->getType());

    if (Val0->getType()->isPointerTy()) return;
    bool fp = Val0->getType()->getScalarType()->isFloatingPointTy();

    int op;
    if (fp) {
      op = Ran->Rand() %
      (CmpInst::LAST_FCMP_PREDICATE - CmpInst::FIRST_FCMP_PREDICATE) +
       CmpInst::FIRST_FCMP_PREDICATE;
    } else {
      op = Ran->Rand() %
      (CmpInst::LAST_ICMP_PREDICATE - CmpInst::FIRST_ICMP_PREDICATE) +
       CmpInst::FIRST_ICMP_PREDICATE;
    }

    Value *V = CmpInst::Create(fp ? Instruction::FCmp : Instruction::ICmp,
                               (CmpInst::Predicate)op, Val0, Val1, "Cmp",
                               BB->getTerminator());
    return PT->push_back(V);
  }
};

} // end anonymous namespace

static void FillFunction(Function *F, Random &R) {
  // Create a legal entry block.
  BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F);
  ReturnInst::Create(F->getContext(), BB);

  // Create the value table.
  Modifier::PieceTable PT;

  // Consider arguments as legal values.
  for (auto &arg : F->args())
    PT.push_back(&arg);

  // List of modifiers which add new random instructions.
  std::vector<std::unique_ptr<Modifier>> Modifiers;
  Modifiers.emplace_back(new LoadModifier(BB, &PT, &R));
  Modifiers.emplace_back(new StoreModifier(BB, &PT, &R));
  auto SM = Modifiers.back().get();
  Modifiers.emplace_back(new ExtractElementModifier(BB, &PT, &R));
  Modifiers.emplace_back(new ShuffModifier(BB, &PT, &R));
  Modifiers.emplace_back(new InsertElementModifier(BB, &PT, &R));
  Modifiers.emplace_back(new BinModifier(BB, &PT, &R));
  Modifiers.emplace_back(new CastModifier(BB, &PT, &R));
  Modifiers.emplace_back(new SelectModifier(BB, &PT, &R));
  Modifiers.emplace_back(new CmpModifier(BB, &PT, &R));

  // Generate the random instructions
  AllocaModifier{BB, &PT, &R}.ActN(5); // Throw in a few allocas
  ConstModifier{BB, &PT, &R}.ActN(40); // Throw in a few constants

  for (unsigned i = 0; i < SizeCL / Modifiers.size(); ++i)
    for (auto &Mod : Modifiers)
      Mod->Act();

  SM->ActN(5); // Throw in a few stores.
}

static void IntroduceControlFlow(Function *F, Random &R) {
  std::vector<Instruction*> BoolInst;
  for (auto &Instr : F->front()) {
    if (Instr.getType() == IntegerType::getInt1Ty(F->getContext()))
      BoolInst.push_back(&Instr);
  }

  std::random_shuffle(BoolInst.begin(), BoolInst.end(), R);

  for (auto *Instr : BoolInst) {
    BasicBlock *Curr = Instr->getParent();
    BasicBlock::iterator Loc = Instr->getIterator();
    BasicBlock *Next = Curr->splitBasicBlock(Loc, "CF");
    Instr->moveBefore(Curr->getTerminator());
    if (Curr != &F->getEntryBlock()) {
      BranchInst::Create(Curr, Next, Instr, Curr->getTerminator());
      Curr->getTerminator()->eraseFromParent();
    }
  }
}

}

int main(int argc, char **argv) {
  using namespace llvm;

  // Init LLVM, call llvm_shutdown() on exit, parse args, etc.
  PrettyStackTraceProgram X(argc, argv);
  cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n");
  llvm_shutdown_obj Y;

  auto M = make_unique<Module>("/tmp/autogen.bc", Context);
  Function *F = GenEmptyFunction(M.get());

  // Pick an initial seed value
  Random R(SeedCL);
  // Generate lots of random instructions inside a single basic block.
  FillFunction(F, R);
  // Break the basic block into many loops.
  IntroduceControlFlow(F, R);

  // Figure out what stream we are supposed to write to...
  std::unique_ptr<tool_output_file> Out;
  // Default to standard output.
  if (OutputFilename.empty())
    OutputFilename = "-";

  std::error_code EC;
  Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None));
  if (EC) {
    errs() << EC.message() << '\n';
    return 1;
  }

  legacy::PassManager Passes;
  Passes.add(createVerifierPass());
  Passes.add(createPrintModulePass(Out->os()));
  Passes.run(*M.get());
  Out->keep();

  return 0;
}
