// possible
//
+#include "config.h"
+//undef those as llvm defines them on its own config.h as well.
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+
#include <stdint.h>
#include <llvm/Support/raw_ostream.h>
+#include <llvm/Support/Host.h>
#include <llvm/PassManager.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/JITMemoryManager.h>
#include <llvm/ExecutionEngine/JITEventListener.h>
#include <llvm/Target/TargetOptions.h>
-#include <llvm/Target/TargetData.h>
#include <llvm/Target/TargetRegisterInfo.h>
+#if LLVM_API_VERSION >= 1
+#include <llvm/IR/Verifier.h>
+#else
#include <llvm/Analysis/Verifier.h>
+#endif
#include <llvm/Analysis/Passes.h>
#include <llvm/Transforms/Scalar.h>
#include <llvm/Support/CommandLine.h>
+#if LLVM_API_VERSION >= 1
+#include "llvm/IR/LegacyPassNameParser.h"
+#else
#include "llvm/Support/PassNameParser.h"
+#endif
#include "llvm/Support/PrettyStackTrace.h"
#include <llvm/CodeGen/Passes.h>
#include <llvm/CodeGen/MachineFunctionPass.h>
#include <llvm/CodeGen/MachineFunction.h>
#include <llvm/CodeGen/MachineFrameInfo.h>
+#include <llvm/IR/Function.h>
+#include <llvm/IR/IRBuilder.h>
+#include <llvm/IR/Module.h>
//#include <llvm/LinkAllPasses.h>
#include "llvm-c/Core.h"
((LLVM_MAJOR_VERSION > (major)) || \
((LLVM_MAJOR_VERSION == (major)) && (LLVM_MINOR_VERSION >= (minor))))
+// extern "C" void LLVMInitializeARMTargetInfo();
+// extern "C" void LLVMInitializeARMTarget ();
+// extern "C" void LLVMInitializeARMTargetMC ();
+
using namespace llvm;
+#ifndef MONO_CROSS_COMPILE
+
class MonoJITMemoryManager : public JITMemoryManager
{
private:
public:
/* Callbacks installed by mono */
AllocCodeMemoryCb *alloc_cb;
+ DlSymCb *dlsym_cb;
MonoJITMemoryManager ();
~MonoJITMemoryManager ();
virtual void deallocateExceptionTable(void*) {
}
- virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID) {
+ virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
+ StringRef SectionName) {
// FIXME:
assert(0);
return NULL;
}
- virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID) {
+ virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
+ StringRef SectionName, bool IsReadOnly) {
// FIXME:
assert(0);
return NULL;
}
+
+ virtual bool applyPermissions(std::string*) {
+ // FIXME:
+ assert(0);
+ return false;
+ }
+
+ virtual bool finalizeMemory(std::string *ErrMsg = 0) {
+ // FIXME:
+ assert(0);
+ return false;
+ }
+
+ virtual void* getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) {
+ void *res;
+ char *err;
+
+ err = dlsym_cb (Name.c_str (), &res);
+ if (err) {
+ outs () << "Unable to resolve: " << Name << ": " << err << "\n";
+ assert(0);
+ return NULL;
+ }
+ return res;
+ }
};
MonoJITMemoryManager::MonoJITMemoryManager ()
{
}
+#else
+
+class MonoJITMemoryManager {
+};
+
+#endif /* !MONO_CROSS_COMPILE */
+
class MonoJITEventListener : public JITEventListener {
public:
* install a profiler hook and reset the code model here.
* This should be inside an ifdef, but we can't include our config.h either,
* since its definitions conflict with LLVM's config.h.
- *
+ * The LLVM mono branch contains a workaround.
*/
- //#if defined(TARGET_X86) || defined(TARGET_AMD64)
-#ifndef LLVM_MONO_BRANCH
- /* The LLVM mono branch contains a workaround, so this is not needed */
- if (Details.MF->getTarget ().getCodeModel () == CodeModel::Large) {
- Details.MF->getTarget ().setCodeModel (CodeModel::Default);
- }
-#endif
- //#endif
-
emitted_cb (wrap (&F), Code, (char*)Code + Size);
}
};
-static MonoJITMemoryManager *mono_mm;
-static MonoJITEventListener *mono_event_listener;
-
-static FunctionPassManager *fpm;
+class MonoEE {
+public:
+ ExecutionEngine *EE;
+ MonoJITMemoryManager *mm;
+ MonoJITEventListener *listener;
+ FunctionPassManager *fpm;
+};
void
-mono_llvm_optimize_method (LLVMValueRef method)
+mono_llvm_optimize_method (MonoEERef eeref, LLVMValueRef method)
{
- verifyFunction (*(unwrap<Function> (method)));
- fpm->run (*unwrap<Function> (method));
+ MonoEE *mono_ee = (MonoEE*)eeref;
+
+ /*
+ * The verifier does some checks on the whole module, leading to quadratic behavior.
+ */
+ //verifyFunction (*(unwrap<Function> (method)));
+ mono_ee->fpm->run (*unwrap<Function> (method));
}
void
{
AtomicCmpXchgInst *ins;
+#if LLVM_API_VERSION >= 1
+ ins = unwrap(builder)->CreateAtomicCmpXchg (unwrap(ptr), unwrap (cmp), unwrap (val), SequentiallyConsistent, SequentiallyConsistent);
+#else
ins = unwrap(builder)->CreateAtomicCmpXchg (unwrap(ptr), unwrap (cmp), unwrap (val), SequentiallyConsistent);
+#endif
return wrap (ins);
}
force_pass_linking (void)
{
// Make sure the rest is linked in, but never executed
- if (getenv ("FOO") != (char*)-1)
+ if (g_getenv ("FOO") != (char*)-1)
return;
// This is a subset of the passes in LinkAllPasses.h
(void) llvm::createBasicAliasAnalysisPass();
(void) llvm::createLibCallAliasAnalysisPass(0);
(void) llvm::createScalarEvolutionAliasAnalysisPass();
- (void) llvm::createBlockPlacementPass();
+ //(void) llvm::createBlockPlacementPass();
(void) llvm::createBreakCriticalEdgesPass();
(void) llvm::createCFGSimplificationPass();
/*
(void) llvm::createLCSSAPass();
(void) llvm::createLICMPass();
(void) llvm::createLazyValueInfoPass();
- (void) llvm::createLoopDependenceAnalysisPass();
+ //(void) llvm::createLoopDependenceAnalysisPass();
/*
(void) llvm::createLoopExtractorPass();
*/
(void) llvm::createReassociatePass();
(void) llvm::createSCCPPass();
(void) llvm::createScalarReplAggregatesPass();
- (void) llvm::createSimplifyLibCallsPass();
+ //(void) llvm::createSimplifyLibCallsPass();
/*
(void) llvm::createSingleLoopExtractorPass();
(void) llvm::createStripSymbolsPass();
(void) llvm::createSinkingPass();
}
-LLVMExecutionEngineRef
-mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb)
+#ifndef MONO_CROSS_COMPILE
+
+static gboolean inited;
+
+static void
+init_llvm (void)
{
- std::string Error;
+ if (inited)
+ return;
force_pass_linking ();
+#ifdef TARGET_ARM
+ LLVMInitializeARMTarget ();
+ LLVMInitializeARMTargetInfo ();
+ LLVMInitializeARMTargetMC ();
+#else
LLVMInitializeX86Target ();
LLVMInitializeX86TargetInfo ();
LLVMInitializeX86TargetMC ();
+#endif
- mono_mm = new MonoJITMemoryManager ();
- mono_mm->alloc_cb = alloc_cb;
+ PassRegistry &Registry = *PassRegistry::getPassRegistry();
+ initializeCore(Registry);
+ initializeScalarOpts(Registry);
+ initializeAnalysis(Registry);
+ initializeIPA(Registry);
+ initializeTransformUtils(Registry);
+ initializeInstCombine(Registry);
+ initializeTarget(Registry);
+
+ llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
+
+ inited = true;
+}
+
+MonoEERef
+mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
+{
+ std::string Error;
+ MonoEE *mono_ee;
+
+ init_llvm ();
- //JITExceptionHandling = true;
- // PrettyStackTrace installs signal handlers which trip up libgc
- DisablePrettyStackTrace = true;
+ mono_ee = new MonoEE ();
+
+ MonoJITMemoryManager *mono_mm = new MonoJITMemoryManager ();
+ mono_mm->alloc_cb = alloc_cb;
+ mono_mm->dlsym_cb = dlsym_cb;
+ mono_ee->mm = mono_mm;
/*
* The Default code model doesn't seem to work on amd64,
opts.JITExceptionHandling = 1;
EngineBuilder b (unwrap (MP));
+ EngineBuilder &eb = b;
+ eb = eb.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true);
+#if LLVM_API_VERSION >= 1
+ StringRef cpu_name = sys::getHostCPUName ();
+ eb = eb.setMCPU (cpu_name);
+#endif
#ifdef TARGET_AMD64
- ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setCodeModel (CodeModel::Large).setAllocateGVsWithCode (true).create ();
-#else
- ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).create ();
+ eb = eb.setCodeModel (CodeModel::Large);
#endif
- g_assert (EE);
-#if 0
- ExecutionEngine *EE = ExecutionEngine::createJIT (unwrap (MP), &Error, mono_mm, CodeGenOpt::Default, true, Reloc::Default, CodeModel::Large);
- if (!EE) {
- errs () << "Unable to create LLVM ExecutionEngine: " << Error << "\n";
- g_assert_not_reached ();
- }
-#endif
+ ExecutionEngine *EE = eb.create ();
+ g_assert (EE);
+ mono_ee->EE = EE;
EE->InstallExceptionTableRegister (exception_cb);
- mono_event_listener = new MonoJITEventListener (emitted_cb);
- EE->RegisterJITEventListener (mono_event_listener);
-
- fpm = new FunctionPassManager (unwrap (MP));
+ MonoJITEventListener *listener = new MonoJITEventListener (emitted_cb);
+ EE->RegisterJITEventListener (listener);
+ mono_ee->listener = listener;
- fpm->add(new TargetData(*EE->getTargetData()));
+ FunctionPassManager *fpm = new FunctionPassManager (unwrap (MP));
+ mono_ee->fpm = fpm;
- PassRegistry &Registry = *PassRegistry::getPassRegistry();
- initializeCore(Registry);
- initializeScalarOpts(Registry);
- //initializeIPO(Registry);
- initializeAnalysis(Registry);
- initializeIPA(Registry);
- initializeTransformUtils(Registry);
- initializeInstCombine(Registry);
- //initializeInstrumentation(Registry);
- initializeTarget(Registry);
-
- llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "", false);
+#if LLVM_API_VERSION >= 1
+ fpm->add(new DataLayoutPass(*EE->getDataLayout()));
+#else
+ fpm->add(new DataLayout(*EE->getDataLayout()));
+#endif
if (PassList.size() > 0) {
/* Use the passes specified by the env variable */
}
} else {
/* Use the same passes used by 'opt' by default, without the ipo passes */
- const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -basiccg -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg -preverify -domtree -verify";
+ const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg";
char **args;
int i;
args = g_strsplit (opts, " ", 1000);
for (i = 0; args [i]; i++)
;
- llvm::cl::ParseCommandLineOptions (i, args, "", false);
+ llvm::cl::ParseCommandLineOptions (i, args, "");
g_strfreev (args);
for (unsigned i = 0; i < PassList.size(); ++i) {
if (PassInf->getNormalCtor())
P = PassInf->getNormalCtor()();
+ g_assert (P->getPassKind () == llvm::PT_Function || P->getPassKind () == llvm::PT_Loop);
fpm->add (P);
}
*/
}
- return wrap(EE);
+ *ee = wrap (EE);
+
+ return mono_ee;
}
void
-mono_llvm_dispose_ee (LLVMExecutionEngineRef ee)
+mono_llvm_dispose_ee (MonoEERef *eeref)
{
- delete unwrap (ee);
+ MonoEE *mono_ee = (MonoEE*)eeref;
- delete fpm;
+ delete mono_ee->EE;
+ delete mono_ee->fpm;
+ //delete mono_ee->mm;
+ delete mono_ee->listener;
+ delete mono_ee;
}
+
+#else
+
+MonoEERef
+mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, FunctionEmittedCb *emitted_cb, ExceptionTableCb *exception_cb, DlSymCb *dlsym_cb, LLVMExecutionEngineRef *ee)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+void
+mono_llvm_dispose_ee (MonoEERef *eeref)
+{
+ g_assert_not_reached ();
+}
+
+/* Not linked in */
+void
+LLVMAddGlobalMapping(LLVMExecutionEngineRef EE, LLVMValueRef Global,
+ void* Addr)
+{
+ g_assert_not_reached ();
+}
+
+void*
+LLVMGetPointerToGlobal(LLVMExecutionEngineRef EE, LLVMValueRef Global)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+#endif /* !MONO_CROSS_COMPILE */