summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Gaeke <gaeke@uiuc.edu>2003-09-04 22:21:24 +0000
committerBrian Gaeke <gaeke@uiuc.edu>2003-09-04 22:21:24 +0000
commitf58815e161c8c91075dd1af7a277314190ebc286 (patch)
tree7c79f34768f6a53fa55d67346e68fdd04b255a5a
parent82d8277ad5862b54341808812bb4016e52347060 (diff)
downloadllvm-f58815e161c8c91075dd1af7a277314190ebc286.tar.gz
llvm-f58815e161c8c91075dd1af7a277314190ebc286.tar.bz2
llvm-f58815e161c8c91075dd1af7a277314190ebc286.tar.xz
Interpreter cleanups:
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
-rw-r--r--include/llvm/ExecutionEngine/ExecutionEngine.h5
-rw-r--r--lib/ExecutionEngine/ExecutionEngine.cpp6
-rw-r--r--lib/ExecutionEngine/Interpreter/Execution.cpp81
-rw-r--r--lib/ExecutionEngine/Interpreter/Interpreter.cpp18
-rw-r--r--lib/ExecutionEngine/Interpreter/Interpreter.h12
-rw-r--r--lib/ExecutionEngine/Interpreter/UserInput.cpp236
-rw-r--r--tools/lli/lli.cpp6
7 files changed, 37 insertions, 327 deletions
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index a0e54c1450..7dc2c0a42c 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -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];
diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp
index 5691a248a0..dbcaf63cde 100644
--- a/lib/ExecutionEngine/ExecutionEngine.cpp
+++ b/lib/ExecutionEngine/ExecutionEngine.cpp
@@ -21,16 +21,16 @@
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;
}
diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp
index 84486c21ee..79c404aae0 100644
--- a/lib/ExecutionEngine/Interpreter/Execution.cpp
+++ b/lib/ExecutionEngine/Interpreter/Execution.cpp
@@ -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;
}
diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.cpp b/lib/ExecutionEngine/Interpreter/Interpreter.cpp
index 6f540e2d1a..4f8c407340 100644
--- a/lib/ExecutionEngine/Interpreter/Interpreter.cpp
+++ b/lib/ExecutionEngine/Interpreter/Interpreter.cpp
@@ -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;
}
diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h
index 459904da6d..47f5c95f15 100644
--- a/lib/ExecutionEngine/Interpreter/Interpreter.h
+++ b/lib/ExecutionEngine/Interpreter/Interpreter.h
@@ -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();
};
diff --git a/lib/ExecutionEngine/Interpreter/UserInput.cpp b/lib/ExecutionEngine/Interpreter/UserInput.cpp
index 3f4493d19b..135c990c65 100644
--- a/lib/ExecutionEngine/Interpreter/UserInput.cpp
+++ b/lib/ExecutionEngine/Interpreter/UserInput.cpp
@@ -5,220 +5,41 @@
//===----------------------------------------------------------------------===//
#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);
- }
-}
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index 36af42168a..d0d1c4997b 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -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");