[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