[llvm-stress] Enhance scalar type selection from command line.
authorPawel Bylica <chfast@gmail.com>
Fri, 10 Jul 2015 10:01:47 +0000 (10:01 +0000)
committerPawel Bylica <chfast@gmail.com>
Fri, 10 Jul 2015 10:01:47 +0000 (10:01 +0000)
llvm-stress command line options like -generate-x86-fp80 has been replaced with one list-like option -types. E.g. llvm-stress -types=x86_fp80,i100,i256,half. Default types (i1, i8, i16, i32, i64, float, double) are always added at the beginning of that list.

Reviewers: hfinkel

Differential Revision: http://reviews.llvm.org/D10667

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241896 91177308-0d34-0410-b5e6-96231b3b80d8

tools/llvm-stress/llvm-stress.cpp

index 727d03f9d6ea4325d256beb03305a71f25a87c93..02b9811252fc28cc8d27cab84259678b22dd14bc 100644 (file)
@@ -31,7 +31,8 @@
 #include <set>
 #include <sstream>
 #include <vector>
-using namespace llvm;
+
+namespace llvm {
 
 static cl::opt<unsigned> SeedCL("seed",
   cl::desc("Seed used for randomness"), cl::init(0));
@@ -42,16 +43,39 @@ static cl::opt<std::string>
 OutputFilename("o", cl::desc("Override output filename"),
                cl::value_desc("filename"));
 
-static cl::opt<bool> GenHalfFloat("generate-half-float",
-  cl::desc("Generate half-length floating-point values"), cl::init(false));
-static cl::opt<bool> GenX86FP80("generate-x86-fp80",
-  cl::desc("Generate 80-bit X86 floating-point values"), cl::init(false));
-static cl::opt<bool> GenFP128("generate-fp128",
-  cl::desc("Generate 128-bit floating-point values"), cl::init(false));
-static cl::opt<bool> GenPPCFP128("generate-ppc-fp128",
-  cl::desc("Generate 128-bit PPC floating-point values"), cl::init(false));
-static cl::opt<bool> GenX86MMX("generate-x86-mmx",
-  cl::desc("Generate X86 MMX floating-point values"), cl::init(false));
+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) {
+    auto &Context = getGlobalContext();
+    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;
+  }
+
+  const char *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
@@ -243,35 +267,22 @@ protected:
 
   /// Pick a random scalar type.
   Type *pickScalarType() {
-    Type *t = nullptr;
-    do {
-      switch (Ran->Rand() % 30) {
-      case 0: t = Type::getInt1Ty(Context); break;
-      case 1: t = Type::getInt8Ty(Context); break;
-      case 2: t = Type::getInt16Ty(Context); break;
-      case 3: case 4:
-      case 5: t = Type::getFloatTy(Context); break;
-      case 6: case 7:
-      case 8: t = Type::getDoubleTy(Context); break;
-      case 9: case 10:
-      case 11: t = Type::getInt32Ty(Context); break;
-      case 12: case 13:
-      case 14: t = Type::getInt64Ty(Context); break;
-      case 15: case 16:
-      case 17: if (GenHalfFloat) t = Type::getHalfTy(Context); break;
-      case 18: case 19:
-      case 20: if (GenX86FP80) t = Type::getX86_FP80Ty(Context); break;
-      case 21: case 22:
-      case 23: if (GenFP128) t = Type::getFP128Ty(Context); break;
-      case 24: case 25:
-      case 26: if (GenPPCFP128) t = Type::getPPC_FP128Ty(Context); break;
-      case 27: case 28:
-      case 29: if (GenX86MMX) t = Type::getX86_MMXTy(Context); break;
-      default: llvm_unreachable("Invalid scalar value");
-      }
-    } while (t == nullptr);
+    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 t;
+    return ScalarTypes[Ran->Rand() % ScalarTypes.size()];
   }
 
   /// Basic block to populate
@@ -665,7 +676,11 @@ static void IntroduceControlFlow(Function *F, Random &R) {
   }
 }
 
+}
+
 int main(int argc, char **argv) {
+  using namespace llvm;
+
   // Init LLVM, call llvm_shutdown() on exit, parse args, etc.
   llvm::PrettyStackTraceProgram X(argc, argv);
   cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n");