Interpreter cleanups:
authorBrian Gaeke <gaeke@uiuc.edu>
Thu, 4 Sep 2003 22:21:24 +0000 (22:21 +0000)
committerBrian Gaeke <gaeke@uiuc.edu>
Thu, 4 Sep 2003 22:21:24 +0000 (22:21 +0000)
Get rid of support for DebugMode (make it always off).
Mung some comments.
Get rid of interpreter's PROFILE_STRUCTURE_FIELDS and PerformExitStuff
 which have been disabled forever.
Get rid of -abort-on-exception (make it always on).
Get rid of user interaction stuff (debug mode innards).
Simplify Interpreter's callMainFunction().

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

include/llvm/ExecutionEngine/ExecutionEngine.h
lib/ExecutionEngine/ExecutionEngine.cpp
lib/ExecutionEngine/Interpreter/Execution.cpp
lib/ExecutionEngine/Interpreter/Interpreter.cpp
lib/ExecutionEngine/Interpreter/Interpreter.h
lib/ExecutionEngine/Interpreter/UserInput.cpp
tools/lli/lli.cpp

index a0e54c14508a23e6939e07e0e2dbb95bd533460d..7dc2c0a42ce16ac2b7d0591527fbdee0f47fd34e 100644 (file)
@@ -49,7 +49,7 @@ public:
                   const char ** envp) = 0;
 
   static ExecutionEngine *create (Module *M, bool ForceInterpreter,
-                                 bool DebugMode, bool TraceMode);
+                                 bool TraceMode);
 
   /// createJIT - Create an return a new JIT compiler if there is one available
   /// for the current target.  Otherwise it returns null.
@@ -58,8 +58,7 @@ public:
 
   /// createInterpreter - Create a new interpreter object.  This can never fail.
   ///
-  static ExecutionEngine *createInterpreter(Module *M, bool DebugMode,
-                                            bool TraceMode);
+  static ExecutionEngine *createInterpreter(Module *M, bool TraceMode);
 
   void addGlobalMapping(const Function *F, void *Addr) {
     void *&CurVal = GlobalAddress[(const GlobalValue*)F];
index 5691a248a06c85e6aecc3936e1a354519ccd224b..dbcaf63cdee879b9f2fb142d6447d71270fd3d90 100644 (file)
 Statistic<> NumInitBytes("lli", "Number of bytes of global vars initialized");
 
 ExecutionEngine *ExecutionEngine::create (Module *M, bool ForceInterpreter,
-                                         bool DebugMode, bool TraceMode) {
+                                         bool TraceMode) {
   ExecutionEngine *EE = 0;
 
   // If there is nothing that is forcing us to use the interpreter, make a JIT.
-  if (!ForceInterpreter && !DebugMode && !TraceMode)
+  if (!ForceInterpreter && !TraceMode)
     EE = VM::create(M);
 
   // If we can't make a JIT, make an interpreter instead.
   if (EE == 0)
-    EE = Interpreter::create(M, DebugMode, TraceMode);
+    EE = Interpreter::create(M, TraceMode);
   return EE;
 }
 
index 84486c21eec225bba37707b7dd68829d5f287bd0..79c404aae06884f598806f7318d0b42424ba788e 100644 (file)
@@ -31,10 +31,6 @@ namespace {
 
   cl::opt<bool>
   ArrayChecksEnabled("array-checks", cl::desc("Enable array bound checks"));
-
-  cl::opt<bool>
-  AbortOnExceptions("abort-on-exception",
-                    cl::desc("Halt execution on a machine exception"));
 }
 
 // Create a TargetData structure to handle memory addressing and size/alignment
@@ -42,14 +38,6 @@ namespace {
 //
 CachedWriter CW;     // Object to accelerate printing of LLVM
 
-#ifdef PROFILE_STRUCTURE_FIELDS
-static cl::opt<bool>
-ProfileStructureFields("profilestructfields", 
-                       cl::desc("Profile Structure Field Accesses"));
-#include <map>
-static std::map<const StructType *, std::vector<unsigned> > FieldAccessCounts;
-#endif
-
 sigjmp_buf SignalRecoverBuffer;
 static bool InInstruction = false;
 
@@ -520,54 +508,6 @@ void Interpreter::visitBinaryOperator(BinaryOperator &I) {
 //                     Terminator Instruction Implementations
 //===----------------------------------------------------------------------===//
 
-// PerformExitStuff - Print out counters and profiling information if
-// applicable...
-void Interpreter::PerformExitStuff() {
-#ifdef PROFILE_STRUCTURE_FIELDS
-  // Print out structure field accounting information...
-  if (!FieldAccessCounts.empty()) {
-    CW << "Profile Field Access Counts:\n";
-    std::map<const StructType *, std::vector<unsigned> >::iterator 
-      I = FieldAccessCounts.begin(), E = FieldAccessCounts.end();
-    for (; I != E; ++I) {
-      std::vector<unsigned> &OfC = I->second;
-      CW << "  '" << (Value*)I->first << "'\t- Sum=";
-      
-      unsigned Sum = 0;
-      for (unsigned i = 0; i < OfC.size(); ++i)
-        Sum += OfC[i];
-      CW << Sum << " - ";
-      
-      for (unsigned i = 0; i < OfC.size(); ++i) {
-        if (i) CW << ", ";
-        CW << OfC[i];
-      }
-      CW << "\n";
-    }
-    CW << "\n";
-
-    CW << "Profile Field Access Percentages:\n";
-    std::cout.precision(3);
-    for (I = FieldAccessCounts.begin(); I != E; ++I) {
-      std::vector<unsigned> &OfC = I->second;
-      unsigned Sum = 0;
-      for (unsigned i = 0; i < OfC.size(); ++i)
-        Sum += OfC[i];
-      
-      CW << "  '" << (Value*)I->first << "'\t- ";
-      for (unsigned i = 0; i < OfC.size(); ++i) {
-        if (i) CW << ", ";
-        CW << double(OfC[i])/Sum;
-      }
-      CW << "\n";
-    }
-    CW << "\n";
-
-    FieldAccessCounts.clear();
-  }
-#endif
-}
-
 void Interpreter::exitCalled(GenericValue GV) {
   if (!QuietMode) {
     std::cout << "Program returned ";
@@ -756,15 +696,6 @@ GenericValue Interpreter::executeGEPOperation(Value *Ptr, User::op_iterator I,
       assert(CPU->getType() == Type::UByteTy);
       unsigned Index = CPU->getValue();
       
-#ifdef PROFILE_STRUCTURE_FIELDS
-      if (ProfileStructureFields) {
-        // Do accounting for this field...
-        std::vector<unsigned> &OfC = FieldAccessCounts[STy];
-        if (OfC.size() == 0) OfC.resize(STy->getElementTypes().size());
-        OfC[Index]++;
-      }
-#endif
-      
       Total += SLO->MemberOffsets[Index];
       Ty = STy->getElementTypes()[Index];
     } else if (const SequentialType *ST = cast<SequentialType>(Ty)) {
@@ -1107,16 +1038,8 @@ bool Interpreter::executeInstruction() {
   //
   if (int SigNo = sigsetjmp(SignalRecoverBuffer, 1)) {
     --SF.CurInst;   // Back up to erroring instruction
-    if (SigNo != SIGINT) {
-      std::cout << "EXCEPTION OCCURRED [" << strsignal(SigNo) << "]:\n";
-      printStackTrace();
-      // If -abort-on-exception was specified, terminate LLI instead of trying
-      // to debug it.
-      //
-      if (AbortOnExceptions) exit(1);
-    } else if (SigNo == SIGINT) {
-      std::cout << "CTRL-C Detected, execution halted.\n";
-    }
+    std::cout << "EXCEPTION OCCURRED [" << strsignal(SigNo) << "]\n";
+    exit(1);
     InInstruction = false;
     return true;
   }
index 6f540e2d1a8a3d0a161c22e6b0b31aaf42e5cde0..4f8c407340af71e64cb5b4ca62bba0f2757af4ae 100644 (file)
@@ -11,7 +11,7 @@
 
 /// create - Create a new interpreter object.  This can never fail.
 ///
-ExecutionEngine *Interpreter::create(Module *M, bool DebugMode, bool TraceMode){
+ExecutionEngine *Interpreter::create(Module *M, bool TraceMode){
   bool isLittleEndian;
   switch (M->getEndianness()) {
   case Module::LittleEndian: isLittleEndian = true; break;
@@ -32,15 +32,15 @@ ExecutionEngine *Interpreter::create(Module *M, bool DebugMode, bool TraceMode){
     break;
   }
 
-  return new Interpreter(M, isLittleEndian, isLongPointer, DebugMode,TraceMode);
+  return new Interpreter(M, isLittleEndian, isLongPointer, TraceMode);
 }
 
 //===----------------------------------------------------------------------===//
 // Interpreter ctor - Initialize stuff
 //
 Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer,
-                         bool DebugMode, bool TraceMode)
-  : ExecutionEngine(M), ExitCode(0), Debug(DebugMode), Trace(TraceMode),
+                         bool TraceMode)
+  : ExecutionEngine(M), ExitCode(0), Trace(TraceMode),
     CurFrame(-1), TD("lli", isLittleEndian, isLongPointer ? 8 : 4,
                      isLongPointer ? 8 : 4, isLongPointer ? 8 : 4) {
 
@@ -59,17 +59,12 @@ int Interpreter::run(const std::string &MainFunction,
                      const char ** envp) {
   // Start interpreter into the main function...
   //
-  if (!callMainFunction(MainFunction, Args) && !Debug) {
-    // If not in debug mode and if the call succeeded, run the code now...
+  if (!callMainFunction(MainFunction, Args)) {
+    // If the call succeeded, run the code now...
     run();
   }
 
   do {
-    // If debug mode, allow the user to interact... also, if the user pressed 
-    // ctrl-c or execution hit an error, enter the event loop...
-    if (Debug || isStopped())
-      handleUserInput();
-
     // If the program has exited, run atexit handlers...
     if (ECStack.empty() && !AtExitHandlers.empty()) {
       callFunction(AtExitHandlers.back(), std::vector<GenericValue>());
@@ -78,7 +73,6 @@ int Interpreter::run(const std::string &MainFunction,
     }
   } while (!ECStack.empty());
 
-  PerformExitStuff();
   return ExitCode;
 }
 
index 459904da6db1772c101ea687b860c9a83ed1dd53..47f5c95f152e3630aef46775cbf6155e7c95b884 100644 (file)
@@ -7,9 +7,6 @@
 #ifndef LLI_INTERPRETER_H
 #define LLI_INTERPRETER_H
 
-// Uncomment this line to enable profiling of structure field accesses.
-//#define PROFILE_STRUCTURE_FIELDS 1
-
 #include "../ExecutionEngine.h"
 #include "../GenericValue.h"
 #include "Support/DataTypes.h"
@@ -74,7 +71,6 @@ struct ExecutionContext {
 //
 class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
   int ExitCode;                // The exit code to be returned by the lli util
-  bool Debug;                  // Debug mode enabled?
   bool Profile;                // Profiling enabled?
   bool Trace;                  // Tracing enabled?
   int CurFrame;                // The current stack frame being inspected
@@ -88,12 +84,12 @@ class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
   std::vector<Function*> AtExitHandlers;
 public:
   Interpreter(Module *M, bool isLittleEndian, bool isLongPointer,
-              bool DebugMode, bool TraceMode);
+              bool TraceMode);
   inline ~Interpreter() { CW.setModule(0); }
 
   /// create - Create an interpreter ExecutionEngine. This can never fail.
   ///
-  static ExecutionEngine *create(Module *M, bool DebugMode, bool TraceMode);
+  static ExecutionEngine *create(Module *M, bool TraceMode);
 
   /// getExitCode - return the code that should be the exit code for the lli
   /// utility.
@@ -220,10 +216,6 @@ private:  // Helper functions
   Value *ChooseOneOption(const std::string &Name,
                          const std::vector<Value*> &Opts);
 
-  // PerformExitStuff - Print out counters and profiling information if
-  // applicable...
-  void PerformExitStuff();
-
   void initializeExecutionEngine();
   void initializeExternalFunctions();
 };
index 3f4493d19be8f30d031a79318f821820bc716966..135c990c652af46f4ab81d13997255ff1bd7bf38 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "Interpreter.h"
-#include "llvm/Bytecode/Reader.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
-#include "llvm/Transforms/Utils/Linker.h"
-#include <algorithm>
-
-enum CommandID {
-  Quit, Help,                                 // Basics
-  Print, Info, List, StackTrace, Up, Down,    // Inspection
-  Next, Step, Run, Finish, Call,              // Control flow changes
-  Break, Watch,                               // Debugging
-  Flush,
-  TraceOpt,                                   // Toggle features
-};
-
-// CommandTable - Build a lookup table for the commands available to the user...
-static struct CommandTableElement {
-  const char *Name;
-  enum CommandID CID;
-
-  inline bool operator<(const CommandTableElement &E) const {
-    return std::string(Name) < std::string(E.Name);
-  }
-  inline bool operator==(const std::string &S) const { 
-    return std::string(Name) == S;
-  }
-} CommandTable[] = {
-  { "quit"     , Quit       }, { "q", Quit }, { "", Quit }, // Empty str = eof
-  { "help"     , Help       }, { "h", Help },
-
-  { "print"    , Print      }, { "p", Print },
-  { "list"     , List       },
-  { "info"     , Info       },
-  { "backtrace", StackTrace }, { "bt", StackTrace }, { "where", StackTrace },
-  { "up"       , Up         },
-  { "down"     , Down       },
-
-  { "next"     , Next       }, { "n", Next },
-  { "step"     , Step       }, { "s", Step },
-  { "run"      , Run        },
-  { "finish"   , Finish     },
-  { "call"     , Call       },
-
-  { "break"    , Break      }, { "b", Break },
-  { "watch"    , Watch      },
-
-  { "flush"    , Flush      },
-
-  { "trace"    , TraceOpt   },
-};
-static CommandTableElement *CommandTableEnd = 
-   CommandTable+sizeof(CommandTable)/sizeof(CommandTable[0]);
-
-
-//===----------------------------------------------------------------------===//
-// handleUserInput - Enter the input loop for the interpreter.  This function
-// returns when the user quits the interpreter.
-//
-void Interpreter::handleUserInput() {
-  bool UserQuit = false;
-
-  // Sort the table...
-  std::sort(CommandTable, CommandTableEnd);
-
-  // Print the instruction that we are stopped at...
-  printCurrentInstruction();
-
-  do {
-    std::string Command;
-    std::cout << "lli> " << std::flush;
-    std::cin >> Command;
-
-    CommandTableElement *E = find(CommandTable, CommandTableEnd, Command);
-
-    if (E == CommandTableEnd) {
-      std::cout << "Error: '" << Command << "' not recognized!\n";
-      continue;
-    }
-
-    switch (E->CID) {
-    case Quit:       UserQuit = true;   break;
-    case Print:
-      std::cin >> Command;
-      print(Command);
-      break;
-    case Info:
-      std::cin >> Command;
-      infoValue(Command);
-      break;
-     
-    case List:       list();            break;
-    case StackTrace: printStackTrace(); break;
-    case Up: 
-      if (CurFrame > 0) { --CurFrame; printStackFrame(); }
-      else std::cout << "Error: Already at root of stack!\n";
-      break;
-    case Down:
-      if ((unsigned)CurFrame < ECStack.size()-1) {
-        ++CurFrame;
-        printStackFrame();
-      } else
-        std::cout << "Error: Already at bottom of stack!\n";
-      break;
-    case Next:       nextInstruction(); break;
-    case Step:       stepInstruction(); break;
-    case Run:        run();             break;
-    case Finish:     finish();          break;
-    case Call:
-      std::cin >> Command;
-      callFunction(Command);    // Enter the specified function
-      finish();                 // Run until it's complete
-      break;
-
-    case TraceOpt:
-      Trace = !Trace;
-      std::cout << "Tracing " << (Trace ? "enabled\n" : "disabled\n");
-      break;
-
-    default:
-      std::cout << "Command '" << Command << "' unimplemented!\n";
-      break;
-    }
-
-  } while (!UserQuit);
-  AtExitHandlers.clear();
-}
-
-//===----------------------------------------------------------------------===//
-// setBreakpoint - Enable a breakpoint at the specified location
-//
-void Interpreter::setBreakpoint(const std::string &Name) {
-  Value *PickedVal = ChooseOneOption(Name, LookupMatchingNames(Name));
-  // TODO: Set a breakpoint on PickedVal
-}
-
-//===----------------------------------------------------------------------===//
-// callFunction - Enter the specified function...
-//
-bool Interpreter::callFunction(const std::string &Name) {
-  std::vector<Value*> Options = LookupMatchingNames(Name);
-
-  for (unsigned i = 0; i < Options.size(); ++i) { // Remove non-fn matches...
-    if (!isa<Function>(Options[i])) {
-      Options.erase(Options.begin()+i);
-      --i;
-    }
-  }
-
-  Value *PickedMeth = ChooseOneOption(Name, Options);
-  if (PickedMeth == 0)
-    return true;
-
-  Function *F = cast<Function>(PickedMeth);
-
-  std::vector<GenericValue> Args;
-  // TODO, get args from user...
-
-  callFunction(F, Args);  // Start executing it...
-
-  // Reset the current frame location to the top of stack
-  CurFrame = ECStack.size()-1;
-
-  return false;
-}
+#include "llvm/Module.h"
 
 // callMainFunction - This is a nasty gross hack that will dissapear when
 // callFunction can parse command line options and stuff for us.
 //
 bool Interpreter::callMainFunction(const std::string &Name,
                                    const std::vector<std::string> &InputArgv) {
-  std::vector<Value*> Options = LookupMatchingNames(Name);
-
-  for (unsigned i = 0; i < Options.size(); ++i) { // Remove non-fn matches...
-    if (!isa<Function>(Options[i])) {
-      Options.erase(Options.begin()+i);
-      --i;
-    }
+  Function *M = getModule().getNamedFunction(Name);
+  if (M == 0) {
+    std::cerr << "Could not find function '" << Name << "' in module!\n";
+    return 1;
   }
-
-  Value *PickedMeth = ChooseOneOption(Name, Options);
-  if (PickedMeth == 0)
-    return true;
-
-  Function *M = cast<Function>(PickedMeth);
   const FunctionType *MT = M->getFunctionType();
 
   std::vector<GenericValue> Args;
-  switch (MT->getParamTypes().size()) {
-  default:
-    std::cout << "Unknown number of arguments to synthesize for '" << Name
-              << "'!\n";
+  if (MT->getParamTypes().size() >= 2) {
+  PointerType *SPP = PointerType::get(PointerType::get(Type::SByteTy));
+  if (MT->getParamTypes()[1] != SPP) {
+    CW << "Second argument of '" << Name << "' should have type: '"
+       << SPP << "'!\n";
     return true;
-  case 2: {
-    PointerType *SPP = PointerType::get(PointerType::get(Type::SByteTy));
-    if (MT->getParamTypes()[1] != SPP) {
-      CW << "Second argument of '" << Name << "' should have type: '"
-         << SPP << "'!\n";
-      return true;
-    }
+  }
+  Args.push_back(PTOGV(CreateArgv(InputArgv)));
+  }
 
-    Args.push_back(PTOGV(CreateArgv(InputArgv)));
+  if (MT->getParamTypes().size() >= 1) {
+  if (!MT->getParamTypes()[0]->isInteger()) {
+    std::cout << "First argument of '" << Name << "' should be an integer!\n";
+    return true;
+  } else {
+    GenericValue GV; GV.UIntVal = InputArgv.size();
+    Args.insert(Args.begin(), GV);
   }
-    // fallthrough
-  case 1:
-    if (!MT->getParamTypes()[0]->isInteger()) {
-      std::cout << "First argument of '" << Name << "' should be an integer!\n";
-      return true;
-    } else {
-      GenericValue GV; GV.UIntVal = InputArgv.size();
-      Args.insert(Args.begin(), GV);
-    }
-    // fallthrough
-  case 0:
-    break;
   }
 
   callFunction(M, Args);  // Start executing it...
@@ -228,20 +49,3 @@ bool Interpreter::callMainFunction(const std::string &Name,
 
   return false;
 }
-
-
-
-void Interpreter::list() {
-  if (ECStack.empty())
-    std::cout << "Error: No program executing!\n";
-  else
-    CW << ECStack[CurFrame].CurFunction;   // Just print the function out...
-}
-
-void Interpreter::printStackTrace() {
-  if (ECStack.empty()) std::cout << "No program executing!\n";
-
-  for (unsigned i = 0; i < ECStack.size(); ++i) {
-    printStackFrame((int)i);
-  }
-}
index 36af42168ad00c3c691c4593abbe7599d2ec20b5..d0d1c4997b43d707ed137a94e85339ad6f417b8e 100644 (file)
@@ -26,8 +26,6 @@ namespace {
   MainFunction ("f", cl::desc("Function to execute"), cl::init("main"),
                cl::value_desc("function name"));
 
-  cl::opt<bool> DebugMode("d", cl::desc("Start program in debugger"));
-
   cl::opt<bool> TraceMode("trace", cl::desc("Enable Tracing"));
 
   cl::opt<bool> ForceInterpreter("force-interpreter",
@@ -60,10 +58,10 @@ int main(int argc, char** argv, const char ** envp) {
   }
 
   ExecutionEngine *EE =
-    ExecutionEngine::create (M, ForceInterpreter, DebugMode, TraceMode);
+    ExecutionEngine::create (M, ForceInterpreter, TraceMode);
   assert (EE && "Couldn't create an ExecutionEngine, not even an interpreter?");
 
-  // Add the module name to the start of the argv vector...
+  // Add the module's name to the start of the vector of arguments to main().
   // But delete .bc first, since programs (and users) might not expect to
   // see it.
   const std::string ByteCodeFileSuffix (".bc");