[vmkit-commits] [vmkit] r200151 - Rename external symbols and make them visible. Inlining don't work to inline Java code into Java code.
Gael Thomas
gael.thomas at lip6.fr
Sun Jan 26 05:12:24 PST 2014
Author: gthomas
Date: Sun Jan 26 07:12:24 2014
New Revision: 200151
URL: http://llvm.org/viewvc/llvm-project?rev=200151&view=rev
Log:
Rename external symbols and make them visible. Inlining don't work to inline Java code into Java code.
Modified:
vmkit/branches/mcjit/Makefile.rules
vmkit/branches/mcjit/include/j3/j3.h
vmkit/branches/mcjit/include/j3/j3method.h
vmkit/branches/mcjit/include/vmkit/compiler.h
vmkit/branches/mcjit/lib/j3/vm/j3method.cc
vmkit/branches/mcjit/lib/j3/vm/j3object.cc
vmkit/branches/mcjit/lib/vmkit-prepare-code/adapt-linkage.cc
vmkit/branches/mcjit/lib/vmkit/compiler.cc
vmkit/branches/mcjit/lib/vmkit/inliner.cc
Modified: vmkit/branches/mcjit/Makefile.rules
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/Makefile.rules?rev=200151&r1=200150&r2=200151&view=diff
==============================================================================
--- vmkit/branches/mcjit/Makefile.rules (original)
+++ vmkit/branches/mcjit/Makefile.rules Sun Jan 26 07:12:24 2014
@@ -296,6 +296,12 @@ endif
ifndef NO_PREPARE_CODE
DO_PREPARE_CODE_LIB=$(LIB_DIR)/vmkit-prepare-code$(SHLIBEXT)
DO_PREPARE_CODE=-load=$(DO_PREPARE_CODE_LIB) -VMKitAdaptLinkage
+RAW=-raw
+
+%.bc: %$(RAW).bc $(DO_PREPARE_CODE_LIB)
+ $(Echo) "Prepare code for vmkit '$(notdir $@)'"
+ $(Verb) $(LLOPT) $(DO_PREPARE_CODE) $(OPTFLAGS) $< -o $@
+
endif
###############################################################################
@@ -316,16 +322,16 @@ $(GEN_MODULE).a: $(OBJ_FILES)
$(Echo) "Linking module '$(notdir $@)'"
$(Verb) ar cru $@ $^ && ranlib $@
-%.o: %.bc $(DO_PREPARE_CODE_LIB)
+%.o: %.bc
$(Echo) "Assembling '$(notdir $<)'"
- $(Verb) $(LLOPT) $(DO_PREPARE_CODE) $(OPTFLAGS) $< -o - | $(LLC) $(LLCFLAGS) -filetype=obj -o $@
+ $(Verb) $(LLC) $(LLCFLAGS) -filetype=obj -o $@ $<
$(BUILD_DIR)/%.o: %.s $(SELF) $(BUILD_DIR)/.dir
$(Echo) "Assembling '$(notdir $<)'"
$(Verb) if $(CLANGXX) $(CXXFLAGS) $(DEPEND_OPTIONS) -c "$<" -o $@; $(DOM)
define define_compile_rule
-$(BUILD_DIR)/%.bc: $4%$1 $(SELF) $(BUILD_DIR)/.dir
+$(BUILD_DIR)/%$(RAW).bc: $4%$1 $(SELF) $(BUILD_DIR)/.dir
$(Echo) "Compiling '$$(notdir $$<)'"
$(Verb) if $2 $3 $(DEPEND_OPTIONS) -emit-llvm -c "$$<" -o $$@; $(DOM)
endef
Modified: vmkit/branches/mcjit/include/j3/j3.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3.h?rev=200151&r1=200150&r2=200151&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3.h (original)
+++ vmkit/branches/mcjit/include/j3/j3.h Sun Jan 26 07:12:24 2014
@@ -158,27 +158,27 @@ namespace j3 {
static JNIEnv* jniEnv();
- static void classNotFoundException(const vmkit::Name* name) __attribute__((noreturn));
- static void noClassDefFoundError(const vmkit::Name* name) __attribute__((noreturn));
- static void classFormatError(J3ObjectType* cl, const char* reason, ...) __attribute__((noreturn));
+ static void classNotFoundException(const vmkit::Name* name) __attribute__((noreturn, noinline));
+ static void noClassDefFoundError(const vmkit::Name* name) __attribute__((noreturn, noinline));
+ static void classFormatError(J3ObjectType* cl, const char* reason, ...) __attribute__((noreturn, noinline));
static void noSuchMethodError(const char* msg,
- J3ObjectType* clName, const vmkit::Name* name, J3Signature* signature) __attribute__((noreturn));
+ J3ObjectType* clName, const vmkit::Name* name, J3Signature* signature) __attribute__((noreturn, noinline));
static void noSuchFieldError(const char* msg,
- J3ObjectType* clName, const vmkit::Name* name, J3Type* type) __attribute__((noreturn));
- static void linkageError(J3Method* method) __attribute__((noreturn));
+ J3ObjectType* clName, const vmkit::Name* name, J3Type* type) __attribute__((noreturn, noinline));
+ static void linkageError(J3Method* method) __attribute__((noreturn, noinline));
- static void outOfMemoryError() __attribute__((noreturn));
+ static void outOfMemoryError() __attribute__((noreturn, noinline));
- static void nullPointerException() __attribute__((noreturn));
- static void classCastException() __attribute__((noreturn));
+ static void nullPointerException() __attribute__((noreturn, noinline));
+ static void classCastException() __attribute__((noreturn, noinline));
- static void negativeArraySizeException(int32_t length) __attribute__((noreturn));
+ static void negativeArraySizeException(int32_t length) __attribute__((noreturn, noinline));
static void arrayStoreException() __attribute__((noreturn));
- static void arrayIndexOutOfBoundsException() __attribute__((noreturn));
+ static void arrayIndexOutOfBoundsException() __attribute__((noreturn, noinline));
- static void illegalMonitorStateException() __attribute__((noreturn));
+ static void illegalMonitorStateException() __attribute__((noreturn, noinline));
- static void illegalArgumentException(const char* msg) __attribute__((noreturn));
+ static void illegalArgumentException(const char* msg) __attribute__((noreturn, noinline));
void printStackTrace();
void uncatchedException(void* e);
Modified: vmkit/branches/mcjit/include/j3/j3method.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3method.h?rev=200151&r1=200150&r2=200151&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3method.h (original)
+++ vmkit/branches/mcjit/include/j3/j3method.h Sun Jan 26 07:12:24 2014
@@ -97,7 +97,7 @@ namespace j3 {
J3Signature::function_t cxxCaller();
void* fnPtr();
llvm::Function* llvmFunction() { return _llvmFunction; } /* overwrite vmkit::Symbol */
- bool isInlinable();
+ uint64_t inlineWeight();
void* functionPointerOrStaticTrampoline();
void* functionPointerOrVirtualTrampoline();
Modified: vmkit/branches/mcjit/include/vmkit/compiler.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/vmkit/compiler.h?rev=200151&r1=200150&r2=200151&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/vmkit/compiler.h (original)
+++ vmkit/branches/mcjit/include/vmkit/compiler.h Sun Jan 26 07:12:24 2014
@@ -23,10 +23,11 @@ namespace vmkit {
class VMKit;
class Symbol : public PermanentObject {
+ uint64_t cachedWeight;
public:
virtual void* getSymbolAddress();
virtual llvm::Function* llvmFunction() { return 0; }
- virtual bool isInlinable() { return 0; }
+ virtual uint64_t inlineWeight();
};
class NativeSymbol : public Symbol {
@@ -37,7 +38,6 @@ namespace vmkit {
llvm::Function* llvmFunction() { return original; }
void* getSymbolAddress() { return addr; }
- virtual bool isInlinable() { return 1; }
};
class CompilationUnit : public llvm::SectionMemoryManager {
Modified: vmkit/branches/mcjit/lib/j3/vm/j3method.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3method.cc?rev=200151&r1=200150&r2=200151&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3method.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3method.cc Sun Jan 26 07:12:24 2014
@@ -31,8 +31,11 @@ J3Method::J3Method(uint16_t access, J3Cl
_index = -1;
}
-bool J3Method::isInlinable() {
- return J3Thread::get()->vm()->options()->enableInlining;
+uint64_t J3Method::inlineWeight() {
+ if(J3Thread::get()->vm()->options()->enableInlining)
+ return vmkit::Symbol::inlineWeight();
+ else
+ return (uint64_t)-1;
}
uint32_t J3Method::interfaceIndex() {
Modified: vmkit/branches/mcjit/lib/j3/vm/j3object.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3object.cc?rev=200151&r1=200150&r2=200151&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3object.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3object.cc Sun Jan 26 07:12:24 2014
@@ -288,11 +288,11 @@ J3Object* J3Object::doNew(J3Class* cl) {
}
void J3Object::monitorEnter(J3Object* obj) {
- J3::internalError("implement me: monitorenter");
+ J3::internalError("implement me: monitor");
}
void J3Object::monitorExit(J3Object* obj) {
- J3::internalError("implement me: monitorexit");
+ J3::internalError("implement me: monitor");
}
uint32_t J3Object::hashCode() {
Modified: vmkit/branches/mcjit/lib/vmkit-prepare-code/adapt-linkage.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/vmkit-prepare-code/adapt-linkage.cc?rev=200151&r1=200150&r2=200151&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/vmkit-prepare-code/adapt-linkage.cc (original)
+++ vmkit/branches/mcjit/lib/vmkit-prepare-code/adapt-linkage.cc Sun Jan 26 07:12:24 2014
@@ -17,26 +17,72 @@
#include <cstdio>
namespace vmkit {
- class VMKitAdaptLinkage : public llvm::FunctionPass {
+ class VMKitAdaptLinkage : public llvm::ModulePass {
public:
static char ID;
- VMKitAdaptLinkage() : llvm::FunctionPass(ID) {}
+ VMKitAdaptLinkage() : llvm::ModulePass(ID) {}
- virtual bool runOnFunction(llvm::Function& function) {
- llvm::Function::LinkageTypes linkage = function.getLinkage();
-
- if(linkage == llvm::GlobalValue::LinkOnceODRLinkage)
- function.setLinkage(llvm::GlobalValue::WeakODRLinkage);
- if(linkage == llvm::GlobalValue::LinkOnceAnyLinkage)
- function.setLinkage(llvm::GlobalValue::WeakAnyLinkage);
- //if(linkage
- //fprintf(stderr, "run on function: %s\n", function.getName().data());
- return 0;
- }
- };
+ virtual bool runOnModule(llvm::Module &module);
+ };
char VMKitAdaptLinkage::ID = 0;
llvm::RegisterPass<VMKitAdaptLinkage> X("VMKitAdaptLinkage",
"Adapt the linkage for vmkit");
+
+ class VMKitRenamer {
+ public:
+ size_t moduleLen;
+ size_t reserved;
+ char* buf;
+
+ VMKitRenamer(llvm::Module* module) {
+ const char* moduleId = module->getModuleIdentifier().data();
+ moduleLen = strlen(moduleId);
+ reserved = 1024;
+ buf = (char*)malloc(moduleLen + reserved + 1);
+ memcpy(buf, moduleId, moduleLen);
+ }
+
+ bool makeVisible(llvm::GlobalValue* gv) {
+ llvm::GlobalValue::LinkageTypes linkage = gv->getLinkage();
+
+ if(linkage == llvm::GlobalValue::LinkOnceODRLinkage) {
+ gv->setLinkage(llvm::GlobalValue::WeakODRLinkage);
+ return 1;
+ }
+
+ if(linkage == llvm::GlobalValue::LinkOnceAnyLinkage) {
+ gv->setLinkage(llvm::GlobalValue::WeakAnyLinkage);
+ return 1;
+ }
+
+ if(linkage == llvm::GlobalValue::PrivateLinkage) {
+ size_t len = strlen(gv->getName().data());
+ if(len > reserved) {
+ reserved = (len << 2);
+ buf = (char*)realloc(buf, moduleLen + reserved + 1);
+ }
+ memcpy(buf + moduleLen, gv->getName().data(), len + 1);
+ gv->setName(buf);
+ gv->setLinkage(llvm::GlobalValue::ExternalLinkage);
+ return 1;
+ }
+
+ return 0;
+ }
+ };
+
+ bool VMKitAdaptLinkage::runOnModule(llvm::Module &module) {
+ bool changed = 0;
+ VMKitRenamer renamer(&module);
+
+ for (llvm::Module::iterator it=module.begin(); it!=module.end(); it++)
+ changed |= renamer.makeVisible(it);
+
+ for (llvm::Module::global_iterator it=module.global_begin(); it!=module.global_end(); it++)
+ changed |= renamer.makeVisible(it);
+
+ return changed;
+ };
}
Modified: vmkit/branches/mcjit/lib/vmkit/compiler.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/vmkit/compiler.cc?rev=200151&r1=200150&r2=200151&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/vmkit/compiler.cc (original)
+++ vmkit/branches/mcjit/lib/vmkit/compiler.cc Sun Jan 26 07:12:24 2014
@@ -27,6 +27,25 @@ void* Symbol::getSymbolAddress() {
Thread::get()->vm()->internalError("implement me: getSymbolAddress");
}
+uint64_t Symbol::inlineWeight() {
+ if(cachedWeight)
+ return cachedWeight;
+
+ uint64_t infinity = (uint64_t)-1;
+
+ if(llvmFunction()->size() > 4)
+ return cachedWeight = infinity;
+
+ uint64_t weight = 0;
+
+ for (llvm::Function::iterator bit=llvmFunction()->begin(); bit!=llvmFunction()->end(); bit++)
+ weight += bit->size();
+
+ weight = weight * 100;
+
+ return cachedWeight = weight;
+}
+
void* CompilationUnit::operator new(size_t n, BumpAllocator* allocator) {
return allocator->allocate(n);
}
Modified: vmkit/branches/mcjit/lib/vmkit/inliner.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/vmkit/inliner.cc?rev=200151&r1=200150&r2=200151&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/vmkit/inliner.cc (original)
+++ vmkit/branches/mcjit/lib/vmkit/inliner.cc Sun Jan 26 07:12:24 2014
@@ -8,6 +8,10 @@
#include "llvm/Transforms/Utils/Cloning.h"
#include "vmkit/compiler.h"
+#include "vmkit/system.h"
+#include "vmkit/vmkit.h"
+
+#include <dlfcn.h>
namespace vmkit {
class FunctionInliner : public llvm::FunctionPass {
@@ -31,112 +35,135 @@ namespace vmkit {
return "Simple inliner";
}
- llvm::InlineCost getInlineCost(llvm::CallSite callSite, llvm::Function* callee) {
- return costAnalysis.getInlineCost(callSite, inlineThreshold);
+ bool ensureLocal(llvm::Function* function, llvm::Function* callee) {
+ /* prevent exernal references because some llvm passes don't like that */
+ if(callee->getParent() != function->getParent()) {
+ //fprintf(stderr, " rewrite local\n");
+ llvm::Function* local = (llvm::Function*)function->getParent()->getOrInsertFunction(callee->getName().data(),
+ callee->getFunctionType());
+ callee->replaceAllUsesWith(local);
+ callee = local;
+ return 1;
+ } else
+ return 0;
}
+
+ Symbol* tryInline(llvm::Function* function, llvm::Function* callee) {
+ if(callee->isIntrinsic())
+ return 0;
+
+ const char* id = callee->getName().data();
+ Symbol* symbol = compiler->getSymbol(id, 0);
+ llvm::Function* bc;
+
+ //fprintf(stderr, " processing: %s => %p\n", id, symbol);
+
+ if(symbol) {
+ bc = symbol->llvmFunction();
+ if(!bc)
+ return 0;
+ } else {
+ bc = callee;
- virtual bool runOnFunction(llvm::Function &function);
- private:
- };
-
- char FunctionInliner::ID = 0;
-
-#if 0
- llvm::RegisterPass<FunctionInliner> X("FunctionInliner",
- "Inlining Pass that inlines evaluator's functions.");
-#endif
-
- bool FunctionInliner::runOnFunction(llvm::Function& function) {
- bool Changed = false;
-
- //fprintf(stderr, "Analyzing: %s\n", function.getName().data());
+ if(callee->isDeclaration() && callee->isMaterializable())
+ callee->Materialize();
- restart:
- for (llvm::Function::iterator bit=function.begin(); bit!=function.end(); bit++) {
- llvm::BasicBlock* bb = bit;
- uint32_t prof = 0;
+ if(callee->isDeclaration())
+ return 0;
+
+ uint8_t* addr = (uint8_t*)dlsym(SELF_HANDLE, id);
+ symbol = new(compiler->allocator()) NativeSymbol(callee, addr);
+ compiler->addSymbol(id, symbol);
+ }
- for(llvm::BasicBlock::iterator it=bb->begin(), prev=0; it!=bb->end() && prof<42; prev=it++) {
- llvm::Instruction *insn = it;
+ //fprintf(stderr, " weight: %lld\n", symbol->inlineWeight());
- //fprintf(stderr, " process: ");
- //insn->dump();
+ return (!bc->hasFnAttribute(llvm::Attribute::NoInline)
+ && (bc->hasFnAttribute(llvm::Attribute::AlwaysInline) ||
+ (!onlyAlwaysInline && (uint64_t)(symbol->inlineWeight()-1) < inlineThreshold))) ? symbol : 0;
+ }
- if (insn->getOpcode() != llvm::Instruction::Call &&
- insn->getOpcode() != llvm::Instruction::Invoke) {
- continue;
- }
+ //llvm::SmallPtrSet<const Function*, 16> NeverInline;
- llvm::CallSite call(insn);
- llvm::Function* callee = call.getCalledFunction();
+ bool runOnFunction(llvm::Function& function) {
+ bool changed = false;
+
+ //fprintf(stderr, "Analyzing: %s\n", function.getName().data());
+
+ restart:
+ for (llvm::Function::iterator bit=function.begin(); bit!=function.end(); bit++) {
+ llvm::BasicBlock* bb = bit;
+ uint32_t prof = 0;
- if(!callee)
- continue;
+ for(llvm::BasicBlock::iterator it=bb->begin(), prev=0; it!=bb->end() && prof<42; prev=it++) {
+ llvm::Instruction *insn = it;
- llvm::Function* bc = callee;
+ //fprintf(stderr, " process: ");
+ //insn->dump();
- if(callee->isDeclaration()) { /* ok, resolve */
- if(callee->isMaterializable())
- callee->Materialize();
+#if 0
+ if(insn->getOpcode() == llvm::Instruction::LandingPad) {
+ llvm::LandingPadInst* lp = (llvm::LandingPadInst*)insn;
+ ensureLocal(&function, (llvm::Function*)lp->getPersonalityFn());
+ continue;
+ }
+#endif
- if(callee->isDeclaration()) {
- Symbol* s = compiler->getSymbol(bc->getName().data(), 0);
-
- if(s && s->isInlinable())
- bc = s->llvmFunction();
+ if (insn->getOpcode() != llvm::Instruction::Call &&
+ insn->getOpcode() != llvm::Instruction::Invoke) {
+ continue;
}
- }
- /* getInlineCost does not like inter-module references */
- if(callee->getParent() != function.getParent()) {
- llvm::Function* local = (llvm::Function*)function.getParent()->getOrInsertFunction(callee->getName(),
- callee->getFunctionType());
- callee->replaceAllUsesWith(local);
- callee = local;
- Changed = 1;
- }
+ llvm::CallSite call(insn);
+ llvm::Function* callee = call.getCalledFunction();
- if(bc && !bc->isDeclaration()) {
- //fprintf(stderr, " processing %s\n", bc->getName().data());
- //function.dump();
- //fprintf(stderr, " %p and %p\n", function.getParent(), callee->getParent());
- //callee->dump();
-
- llvm::InlineCost cost = getInlineCost(call, bc);
-
- //fprintf(stderr, " Inlining: %s ", bc->getName().data());
- //if(cost.isAlways())
- //fprintf(stderr, " is always\n");
- //else if(cost.isNever())
- //fprintf(stderr, " is never\n");
- //else
- //fprintf(stderr, " cost: %d (=> %s)\n", cost.getCost(), !cost ? "false" : "true");
+ if(!callee)
+ continue;
- if(cost.isAlways()) {// || (!onlyAlwaysInline && !cost.isNever() && cost)) {
+ Symbol* symbol = tryInline(&function, callee);
+ llvm::Function* bc;
+
+ if(symbol && (bc = symbol->llvmFunction()) != &function) {
if(bc != callee)
callee->replaceAllUsesWith(bc);
-
+
+ //fprintf(stderr, " inlining: %s\n", bc->getName().data());
+ //bc->dump();
llvm::InlineFunctionInfo ifi(0);
bool isInlined = llvm::InlineFunction(call, ifi, false);
- Changed |= isInlined;
+ changed |= isInlined;
if(isInlined) {
- // prof++;
- // it = prev ? prev : bb->begin();
- // continue;
+ prof++;
+ //it = prev ? prev : bb->begin();
+ //continue;
+ //fprintf(stderr, "... restart ....\n");
goto restart;
}
- }
+ } else
+ changed |= ensureLocal(&function, callee);
}
}
+
+ //#if 0
+ if(changed) {
+ //function.dump();
+ //abort();
+ }
+ //#endif
+
+ return changed;
}
+ };
- //function.dump();
+ char FunctionInliner::ID = 0;
- return Changed;
- }
+#if 0
+ llvm::RegisterPass<FunctionInliner> X("FunctionInliner",
+ "Inlining Pass that inlines evaluator's functions.");
+#endif
llvm::FunctionPass* createFunctionInlinerPass(CompilationUnit* compiler, bool onlyAlwaysInline) {
- return new FunctionInliner(compiler, 2, onlyAlwaysInline);
+ return new FunctionInliner(compiler, 2000, onlyAlwaysInline);
}
}
More information about the vmkit-commits
mailing list