mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 06:30:16 +00:00
Pass around IntrinsicLowering instances as appropriate.
Reimplement the Interpreters implementation of va_* to be more direct. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10627 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f8742b3e03
commit
7301178aac
@ -17,6 +17,7 @@
|
|||||||
#include "JIT/JIT.h"
|
#include "JIT/JIT.h"
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
|
#include "llvm/IntrinsicLowering.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/Module.h"
|
||||||
#include "llvm/ModuleProvider.h"
|
#include "llvm/ModuleProvider.h"
|
||||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||||
@ -105,20 +106,23 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn,
|
|||||||
/// NULL is returned.
|
/// NULL is returned.
|
||||||
///
|
///
|
||||||
ExecutionEngine *ExecutionEngine::create(ModuleProvider *MP,
|
ExecutionEngine *ExecutionEngine::create(ModuleProvider *MP,
|
||||||
bool ForceInterpreter) {
|
bool ForceInterpreter,
|
||||||
|
IntrinsicLowering *IL) {
|
||||||
ExecutionEngine *EE = 0;
|
ExecutionEngine *EE = 0;
|
||||||
|
|
||||||
// Unless the interpreter was explicitly selected, make a JIT.
|
// Unless the interpreter was explicitly selected, try making a JIT.
|
||||||
if (!ForceInterpreter)
|
if (!ForceInterpreter)
|
||||||
EE = JIT::create(MP);
|
EE = JIT::create(MP, IL);
|
||||||
|
|
||||||
// If we can't make a JIT, make an interpreter instead.
|
// If we can't make a JIT, make an interpreter instead.
|
||||||
try {
|
try {
|
||||||
if (EE == 0)
|
if (EE == 0)
|
||||||
EE = Interpreter::create(MP->materializeModule());
|
EE = Interpreter::create(MP->materializeModule(), IL);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
EE = 0;
|
EE = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EE == 0) delete IL;
|
||||||
return EE;
|
return EE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,11 +12,12 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#define DEBUG_TYPE "interpreter"
|
#define DEBUG_TYPE "interpreter"
|
||||||
|
|
||||||
#include "Interpreter.h"
|
#include "Interpreter.h"
|
||||||
#include "llvm/Instructions.h"
|
|
||||||
#include "llvm/DerivedTypes.h"
|
|
||||||
#include "llvm/Constants.h"
|
#include "llvm/Constants.h"
|
||||||
|
#include "llvm/DerivedTypes.h"
|
||||||
|
#include "llvm/Instructions.h"
|
||||||
|
#include "llvm/IntrinsicLowering.h"
|
||||||
|
#include "llvm/Intrinsics.h"
|
||||||
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
#include "llvm/Support/GetElementPtrTypeIterator.h"
|
||||||
#include "Support/Statistic.h"
|
#include "Support/Statistic.h"
|
||||||
#include "Support/Debug.h"
|
#include "Support/Debug.h"
|
||||||
@ -25,15 +26,15 @@ using namespace llvm;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed");
|
Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed");
|
||||||
}
|
|
||||||
|
|
||||||
namespace llvm {
|
|
||||||
Interpreter *TheEE = 0;
|
Interpreter *TheEE = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Value Manipulation code
|
// Value Manipulation code
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2,
|
static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2,
|
||||||
const Type *Ty);
|
const Type *Ty);
|
||||||
static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2,
|
static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2,
|
||||||
@ -764,6 +765,36 @@ void Interpreter::visitStoreInst(StoreInst &I) {
|
|||||||
|
|
||||||
void Interpreter::visitCallSite(CallSite CS) {
|
void Interpreter::visitCallSite(CallSite CS) {
|
||||||
ExecutionContext &SF = ECStack.back();
|
ExecutionContext &SF = ECStack.back();
|
||||||
|
|
||||||
|
// Check to see if this is an intrinsic function call...
|
||||||
|
if (Function *F = CS.getCalledFunction())
|
||||||
|
switch (F->getIntrinsicID()) {
|
||||||
|
case Intrinsic::va_start: // va_start: implemented by getFirstVarArg()
|
||||||
|
SetValue(CS.getInstruction(), getFirstVarArg(), SF);
|
||||||
|
return;
|
||||||
|
case Intrinsic::va_end: // va_end is a noop for the interpreter
|
||||||
|
return;
|
||||||
|
case Intrinsic::va_copy: // va_copy: dest = src
|
||||||
|
SetValue(CS.getInstruction(), getOperandValue(*CS.arg_begin(), SF), SF);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
// If it is an unknown intrinsic function, using the intrinsic lowering
|
||||||
|
// class to transform it into hopefully tasty LLVM code.
|
||||||
|
//
|
||||||
|
Instruction *Prev = CS.getInstruction()->getPrev();
|
||||||
|
BasicBlock *Parent = CS.getInstruction()->getParent();
|
||||||
|
IL->LowerIntrinsicCall(cast<CallInst>(CS.getInstruction()));
|
||||||
|
|
||||||
|
// Restore the CurInst pointer to the first instruction newly inserted, if
|
||||||
|
// any.
|
||||||
|
if (!Prev) {
|
||||||
|
SF.CurInst = Parent->begin();
|
||||||
|
} else {
|
||||||
|
SF.CurInst = Prev;
|
||||||
|
++SF.CurInst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SF.Caller = CS;
|
SF.Caller = CS;
|
||||||
std::vector<GenericValue> ArgVals;
|
std::vector<GenericValue> ArgVals;
|
||||||
const unsigned NumArgs = SF.Caller.arg_size();
|
const unsigned NumArgs = SF.Caller.arg_size();
|
||||||
|
@ -676,28 +676,6 @@ GenericValue lle_X_fprintf(FunctionType *M, const vector<GenericValue> &Args) {
|
|||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// LLVM Intrinsic Functions...
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
|
|
||||||
// <va_list> llvm.va_start() - Implement the va_start operation...
|
|
||||||
GenericValue llvm_va_start(FunctionType *F, const vector<GenericValue> &Args) {
|
|
||||||
assert(Args.size() == 0);
|
|
||||||
return TheInterpreter->getFirstVarArg();
|
|
||||||
}
|
|
||||||
|
|
||||||
// void llvm.va_end(<va_list> *) - Implement the va_end operation...
|
|
||||||
GenericValue llvm_va_end(FunctionType *F, const vector<GenericValue> &Args) {
|
|
||||||
assert(Args.size() == 1);
|
|
||||||
return GenericValue(); // Noop!
|
|
||||||
}
|
|
||||||
|
|
||||||
// <va_list> llvm.va_copy(<va_list>) - Implement the va_copy operation...
|
|
||||||
GenericValue llvm_va_copy(FunctionType *F, const vector<GenericValue> &Args) {
|
|
||||||
assert(Args.size() == 1);
|
|
||||||
return Args[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End extern "C"
|
} // End extern "C"
|
||||||
|
|
||||||
|
|
||||||
@ -749,9 +727,5 @@ void Interpreter::initializeExternalFunctions() {
|
|||||||
FuncNames["lle_X_ungetc"] = lle_X_ungetc;
|
FuncNames["lle_X_ungetc"] = lle_X_ungetc;
|
||||||
FuncNames["lle_X_fprintf"] = lle_X_fprintf;
|
FuncNames["lle_X_fprintf"] = lle_X_fprintf;
|
||||||
FuncNames["lle_X_freopen"] = lle_X_freopen;
|
FuncNames["lle_X_freopen"] = lle_X_freopen;
|
||||||
|
|
||||||
FuncNames["lle_X_llvm.va_start"]= llvm_va_start;
|
|
||||||
FuncNames["lle_X_llvm.va_end"] = llvm_va_end;
|
|
||||||
FuncNames["lle_X_llvm.va_copy"] = llvm_va_copy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,13 +14,14 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "Interpreter.h"
|
#include "Interpreter.h"
|
||||||
#include "llvm/Module.h"
|
#include "llvm/IntrinsicLowering.h"
|
||||||
#include "llvm/DerivedTypes.h"
|
#include "llvm/DerivedTypes.h"
|
||||||
|
#include "llvm/Module.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
/// create - Create a new interpreter object. This can never fail.
|
/// create - Create a new interpreter object. This can never fail.
|
||||||
///
|
///
|
||||||
ExecutionEngine *Interpreter::create(Module *M){
|
ExecutionEngine *Interpreter::create(Module *M, IntrinsicLowering *IL) {
|
||||||
bool isLittleEndian = false;
|
bool isLittleEndian = false;
|
||||||
switch (M->getEndianness()) {
|
switch (M->getEndianness()) {
|
||||||
case Module::LittleEndian: isLittleEndian = true; break;
|
case Module::LittleEndian: isLittleEndian = true; break;
|
||||||
@ -41,22 +42,29 @@ ExecutionEngine *Interpreter::create(Module *M){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Interpreter(M, isLittleEndian, isLongPointer);
|
return new Interpreter(M, isLittleEndian, isLongPointer, IL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Interpreter ctor - Initialize stuff
|
// Interpreter ctor - Initialize stuff
|
||||||
//
|
//
|
||||||
Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer)
|
Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer,
|
||||||
|
IntrinsicLowering *il)
|
||||||
: ExecutionEngine(M), ExitCode(0),
|
: ExecutionEngine(M), ExitCode(0),
|
||||||
TD("lli", isLittleEndian, isLongPointer ? 8 : 4, isLongPointer ? 8 : 4,
|
TD("lli", isLittleEndian, isLongPointer ? 8 : 4, isLongPointer ? 8 : 4,
|
||||||
isLongPointer ? 8 : 4) {
|
isLongPointer ? 8 : 4), IL(il) {
|
||||||
|
|
||||||
setTargetData(TD);
|
setTargetData(TD);
|
||||||
// Initialize the "backend"
|
// Initialize the "backend"
|
||||||
initializeExecutionEngine();
|
initializeExecutionEngine();
|
||||||
initializeExternalFunctions();
|
initializeExternalFunctions();
|
||||||
emitGlobals();
|
emitGlobals();
|
||||||
|
|
||||||
|
if (IL == 0) IL = new DefaultIntrinsicLowering();
|
||||||
|
}
|
||||||
|
|
||||||
|
Interpreter::~Interpreter() {
|
||||||
|
delete IL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::runAtExitHandlers () {
|
void Interpreter::runAtExitHandlers () {
|
||||||
|
@ -79,6 +79,7 @@ struct ExecutionContext {
|
|||||||
class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
|
class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
|
||||||
int ExitCode; // The exit code to be returned by the lli util
|
int ExitCode; // The exit code to be returned by the lli util
|
||||||
TargetData TD;
|
TargetData TD;
|
||||||
|
IntrinsicLowering *IL;
|
||||||
|
|
||||||
// The runtime stack of executing code. The top of the stack is the current
|
// The runtime stack of executing code. The top of the stack is the current
|
||||||
// function record.
|
// function record.
|
||||||
@ -89,17 +90,20 @@ class Interpreter : public ExecutionEngine, public InstVisitor<Interpreter> {
|
|||||||
std::vector<Function*> AtExitHandlers;
|
std::vector<Function*> AtExitHandlers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Interpreter(Module *M, bool isLittleEndian, bool isLongPointer);
|
Interpreter(Module *M, bool isLittleEndian, bool isLongPointer,
|
||||||
inline ~Interpreter() { }
|
IntrinsicLowering *IL);
|
||||||
|
~Interpreter();
|
||||||
|
|
||||||
/// runAtExitHandlers - Run any functions registered by the program's calls to
|
/// runAtExitHandlers - Run any functions registered by the program's calls to
|
||||||
/// atexit(3), which we intercept and store in AtExitHandlers.
|
/// atexit(3), which we intercept and store in AtExitHandlers.
|
||||||
///
|
///
|
||||||
void runAtExitHandlers();
|
void runAtExitHandlers();
|
||||||
|
|
||||||
/// create - Create an interpreter ExecutionEngine. This can never fail.
|
/// create - Create an interpreter ExecutionEngine. This can never fail. The
|
||||||
|
/// specified IntrinsicLowering implementation will be deleted when the
|
||||||
|
/// Interpreter execution engine is destroyed.
|
||||||
///
|
///
|
||||||
static ExecutionEngine *create(Module *M);
|
static ExecutionEngine *create(Module *M, IntrinsicLowering *IL);
|
||||||
|
|
||||||
/// run - Start execution with the specified function and arguments.
|
/// run - Start execution with the specified function and arguments.
|
||||||
///
|
///
|
||||||
|
@ -44,9 +44,11 @@ public:
|
|||||||
~JIT();
|
~JIT();
|
||||||
|
|
||||||
/// create - Create an return a new JIT compiler if there is one available
|
/// create - Create an return a new JIT compiler if there is one available
|
||||||
/// for the current target. Otherwise, return null.
|
/// for the current target. Otherwise, return null. If the JIT is created
|
||||||
|
/// successfully, it takes responsibility for deleting the specified
|
||||||
|
/// IntrinsicLowering implementation.
|
||||||
///
|
///
|
||||||
static ExecutionEngine *create(ModuleProvider *MP);
|
static ExecutionEngine *create(ModuleProvider *MP, IntrinsicLowering *IL = 0);
|
||||||
|
|
||||||
/// run - Start execution with the specified function and arguments.
|
/// run - Start execution with the specified function and arguments.
|
||||||
///
|
///
|
||||||
|
@ -53,8 +53,9 @@ namespace {
|
|||||||
/// create - Create an return a new JIT compiler if there is one available
|
/// create - Create an return a new JIT compiler if there is one available
|
||||||
/// for the current target. Otherwise, return null.
|
/// for the current target. Otherwise, return null.
|
||||||
///
|
///
|
||||||
ExecutionEngine *JIT::create(ModuleProvider *MP) {
|
ExecutionEngine *JIT::create(ModuleProvider *MP, IntrinsicLowering *IL) {
|
||||||
TargetMachine* (*TargetMachineAllocator)(const Module &) = 0;
|
TargetMachine* (*TargetMachineAllocator)(const Module &,
|
||||||
|
IntrinsicLowering *IL) = 0;
|
||||||
|
|
||||||
// Allow a command-line switch to override what *should* be the default target
|
// Allow a command-line switch to override what *should* be the default target
|
||||||
// machine for this platform. This allows for debugging a Sparc JIT on X86 --
|
// machine for this platform. This allows for debugging a Sparc JIT on X86 --
|
||||||
@ -80,7 +81,7 @@ ExecutionEngine *JIT::create(ModuleProvider *MP) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Allocate a target...
|
// Allocate a target...
|
||||||
TargetMachine *Target = TargetMachineAllocator(*MP->getModule());
|
TargetMachine *Target = TargetMachineAllocator(*MP->getModule(), IL);
|
||||||
assert(Target && "Could not allocate target machine!");
|
assert(Target && "Could not allocate target machine!");
|
||||||
|
|
||||||
// If the target supports JIT code generation, return a new JIT now.
|
// If the target supports JIT code generation, return a new JIT now.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user