[vmkit-commits] [vmkit] r199849 - Better inlining. However, I have two problems with this inliner:

Gael Thomas gael.thomas at lip6.fr
Wed Jan 22 15:05:39 PST 2014


Author: gthomas
Date: Wed Jan 22 17:05:38 2014
New Revision: 199849

URL: http://llvm.org/viewvc/llvm-project?rev=199849&view=rev
Log:
Better inlining. However, I have two problems with this inliner:
- the inline cost analyzer provided by llvm has to analyze the whole call graph. Inadequate for a JIT. 
- strings (char*) defined in C are not visible with dlsym. So I can not inline functions that manipulate strings (or other symbols that are not externally visible). 



Modified:
    vmkit/branches/mcjit/include/j3/j3meta.def
    vmkit/branches/mcjit/include/vmkit/compiler.h
    vmkit/branches/mcjit/include/vmkit/inliner.h
    vmkit/branches/mcjit/lib/j3/vm/j3.cc
    vmkit/branches/mcjit/lib/j3/vm/j3classloader.cc
    vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc
    vmkit/branches/mcjit/lib/j3/vm/j3options.cc
    vmkit/branches/mcjit/lib/vmkit/compiler.cc
    vmkit/branches/mcjit/lib/vmkit/inliner.cc
    vmkit/branches/mcjit/tools/vmkit-extract/main.cc

Modified: vmkit/branches/mcjit/include/j3/j3meta.def
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/j3/j3meta.def?rev=199849&r1=199848&r2=199849&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/j3/j3meta.def (original)
+++ vmkit/branches/mcjit/include/j3/j3meta.def Wed Jan 22 17:05:38 2014
@@ -1,7 +1,7 @@
 _x(funcJ3ObjectTypeResolve,         "j3::J3Type::resolve()", 0)
 _x(funcJ3ObjectTypeInitialise,      "j3::J3Type::initialise()", 0)
 _x(funcJ3TypeJavaClass,             "j3::J3Type::javaClass(bool, j3::J3ObjectHandle*)", 0)
-_x(funcJniEnv,                      "j3::J3::jniEnv()", 1)
+_x(funcJniEnv,                      "j3::J3::jniEnv()", 0)
 _x(funcJ3ArrayObjectMultianewArray, "j3::J3ArrayObject::multianewArray(j3::J3ArrayClass*, unsigned int, unsigned int*)", 0)
 _x(funcJ3ObjectAllocate,            "j3::J3Object::allocate(j3::J3VirtualTable*, unsigned long)", 0)
 _x(funcJ3ObjectMonitorEnter,        "j3::J3Object::monitorEnter(j3::J3Object*)", 0)
@@ -10,10 +10,10 @@ _x(funcThrowException,              "vmk
 _x(funcReplayException,             "j3::J3Thread::replayException()", 0)
 _x(funcClassCastException,          "j3::J3::classCastException()", 0)
 _x(funcNullPointerException,        "j3::J3::nullPointerException()", 0)
-_x(funcJ3ThreadPushHandle,          "j3::J3Thread::push(j3::J3ObjectHandle*)", 1)
-_x(funcJ3ThreadPush,                "j3::J3Thread::push(j3::J3Object*)", 1)
-_x(funcJ3ThreadTell,                "j3::J3Thread::tell()", 1)
-_x(funcJ3ThreadRestore,             "j3::J3Thread::restore(j3::J3ObjectHandle*)", 1)
+_x(funcJ3ThreadPushHandle,          "j3::J3Thread::push(j3::J3ObjectHandle*)", 0)
+_x(funcJ3ThreadPush,                "j3::J3Thread::push(j3::J3Object*)", 0)
+_x(funcJ3ThreadTell,                "j3::J3Thread::tell()", 0)
+_x(funcJ3ThreadRestore,             "j3::J3Thread::restore(j3::J3ObjectHandle*)", 0)
 _x(funcEchoDebugEnter,              "j3::J3CodeGen::echoDebugEnter(unsigned int, char const*, ...)", 0)
 _x(funcEchoDebugExecute,            "j3::J3CodeGen::echoDebugExecute(unsigned int, char const*, ...)", 0)
 _x(funcEchoElement,                 "j3::J3CodeGen::echoElement(unsigned int, unsigned int, unsigned long)", 0)
@@ -23,3 +23,8 @@ _x(funcGXXPersonality,              "__g
 _x(funcCXABeginCatch,               "__cxa_begin_catch", 0)
 _x(funcCXAEndCatch,                 "__cxa_end_catch", 0)
 _x(funcFake,                        "j3::J3::forceSymbolDefinition()", 0)
+
+_x(funcJ3ThreadGet,                 "j3::J3Thread::get()", 0)
+_x(funcVMKitThreadGet,              "vmkit::Thread::get()", 0)
+_x(funcVMKitThreadGetP,             "vmkit::Thread::get(void*)", 0)
+_x(funcJ3ThreadJniEnv,              "j3::J3Thread::jniEnv()", 0)

Modified: vmkit/branches/mcjit/include/vmkit/compiler.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/vmkit/compiler.h?rev=199849&r1=199848&r2=199849&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/vmkit/compiler.h (original)
+++ vmkit/branches/mcjit/include/vmkit/compiler.h Wed Jan 22 17:05:38 2014
@@ -55,7 +55,7 @@ namespace vmkit {
 	public:
 		void* operator new(size_t n, BumpAllocator* allocator);
 
-		CompilationUnit(BumpAllocator* allocator, const char* id);
+		CompilationUnit(BumpAllocator* allocator, const char* id, bool runInlinePass, bool onlyAlwaysInline);
 		~CompilationUnit();
 
 		static void destroy(CompilationUnit* unit);

Modified: vmkit/branches/mcjit/include/vmkit/inliner.h
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/include/vmkit/inliner.h?rev=199849&r1=199848&r2=199849&view=diff
==============================================================================
--- vmkit/branches/mcjit/include/vmkit/inliner.h (original)
+++ vmkit/branches/mcjit/include/vmkit/inliner.h Wed Jan 22 17:05:38 2014
@@ -6,7 +6,7 @@
 namespace vmkit {
 	class CompilationUnit;
 
-	llvm::FunctionPass* createFunctionInlinerPass(CompilationUnit* compiler);
+	llvm::FunctionPass* createFunctionInlinerPass(CompilationUnit* compiler, bool onlyAlwaysInline);
 }
 
 #endif

Modified: vmkit/branches/mcjit/lib/j3/vm/j3.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3.cc?rev=199849&r1=199848&r2=199849&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3.cc Wed Jan 22 17:05:38 2014
@@ -97,11 +97,13 @@ void J3::run() {
 
 	introspect();
 
+	if(options()->isAOT) {
 #define _x(name, id, forceInline)																				\
-	if(forceInline)																												\
-		introspectFunction(0, id)->addFnAttr(llvm::Attribute::AlwaysInline);
+		if(forceInline)																											\
+			introspectFunction(0, id)->addFnAttr(llvm::Attribute::AlwaysInline);
 #include "j3/j3meta.def"
 #undef _x
+	}
 
 	vmkit::BumpAllocator* loaderAllocator = vmkit::BumpAllocator::create();
 	initialClassLoader = new(loaderAllocator) J3InitialClassLoader(loaderAllocator);

Modified: vmkit/branches/mcjit/lib/j3/vm/j3classloader.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3classloader.cc?rev=199849&r1=199848&r2=199849&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3classloader.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3classloader.cc Wed Jan 22 17:05:38 2014
@@ -23,7 +23,7 @@ using namespace j3;
 J3ClassLoader::J3InterfaceMethodLess J3ClassLoader::j3InterfaceMethodLess;
 
 J3ClassLoader::J3ClassLoader(J3ObjectHandle* javaClassLoader, vmkit::BumpAllocator* allocator) 
-	: CompilationUnit(allocator, "class-loader"),
+	: CompilationUnit(allocator, "class-loader", J3Thread::get()->vm()->options()->enableInlining, J3Thread::get()->vm()->options()->isAOT),
 		_globalReferences(allocator),
 		_staticObjectHandles(allocator),
 		_staticObjects(allocator),

Modified: vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc?rev=199849&r1=199848&r2=199849&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3codegen.cc Wed Jan 22 17:05:38 2014
@@ -72,8 +72,8 @@ J3CodeGen::J3CodeGen(vmkit::BumpAllocato
 	uintPtrTy = vm->dataLayout()->getIntPtrType(module->getContext());
 	nullValue = llvm::ConstantPointerNull::get((llvm::PointerType*)vm->typeJ3ObjectPtr);
 
-#define _x(name, id, forceInline)											\
-	name = vm->introspectFunction(forceInline ? 0 : module, id);
+#define _x(name, id, forceInline)																				\
+	name = vm->introspectFunction(module, id);
 #include "j3/j3meta.def"
 #undef _x
 

Modified: vmkit/branches/mcjit/lib/j3/vm/j3options.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/j3/vm/j3options.cc?rev=199849&r1=199848&r2=199849&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/j3/vm/j3options.cc (original)
+++ vmkit/branches/mcjit/lib/j3/vm/j3options.cc Wed Jan 22 17:05:38 2014
@@ -78,7 +78,6 @@ void J3CmdLineParser::process() {
 		else if(opteq("-Xaot")) {
 			options->isAOT = 1;
 			options->aotFile = argv[++cur];
-			options->enableInlining = 0;
 		} else if(opteq("-Xno-aot"))
 			options->isAOT = 0;
 		else if(optbeg("-X"))
@@ -123,6 +122,9 @@ void J3CmdLineParser::process() {
 
 	options->args = argv + cur;
 	options->nbArgs = argc - cur;
+
+	if(options->isAOT)
+		options->enableInlining = 1;
 }
 
 void J3CmdLineParser::help() {

Modified: vmkit/branches/mcjit/lib/vmkit/compiler.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/vmkit/compiler.cc?rev=199849&r1=199848&r2=199849&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/vmkit/compiler.cc (original)
+++ vmkit/branches/mcjit/lib/vmkit/compiler.cc Wed Jan 22 17:05:38 2014
@@ -34,7 +34,7 @@ void* CompilationUnit::operator new(size
 void  CompilationUnit::operator delete(void* self) {
 }
 
-CompilationUnit::CompilationUnit(BumpAllocator* allocator, const char* id) :
+CompilationUnit::CompilationUnit(BumpAllocator* allocator, const char* id, bool runInlinePass, bool onlyAlwaysInline) :
 	_symbolTable(vmkit::Util::char_less, allocator) {
 	_allocator = allocator;
 	pthread_mutex_init(&_mutexSymbolTable, 0);
@@ -64,7 +64,8 @@ CompilationUnit::CompilationUnit(BumpAll
 	pm->add(llvm::createBasicAliasAnalysisPass());
 #endif
 
-	pm->add(vmkit::createFunctionInlinerPass(this));
+	if(runInlinePass || onlyAlwaysInline)
+		pm->add(vmkit::createFunctionInlinerPass(this, onlyAlwaysInline));
 	pm->add(llvm::createCFGSimplificationPass());      // Clean up disgusting code
 
 #if 0
@@ -139,6 +140,7 @@ Symbol* CompilationUnit::getSymbol(const
 		res = it->second;
 
 	pthread_mutex_unlock(&_mutexSymbolTable);
+
 	return res;
 }
 

Modified: vmkit/branches/mcjit/lib/vmkit/inliner.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/lib/vmkit/inliner.cc?rev=199849&r1=199848&r2=199849&view=diff
==============================================================================
--- vmkit/branches/mcjit/lib/vmkit/inliner.cc (original)
+++ vmkit/branches/mcjit/lib/vmkit/inliner.cc Wed Jan 22 17:05:38 2014
@@ -3,7 +3,6 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CallSite.h"
-//#include "llvm/Target/TargetData.h"
 #include "llvm/Analysis/InlineCost.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/Transforms/Utils/Cloning.h"
@@ -15,14 +14,17 @@ namespace vmkit {
   public:
     static char ID;
 
-		CompilationUnit*                             compiler;
-		llvm::InlineCostAnalysis                     costAnalysis;
-		unsigned int                                 inlineThreshold;
+		CompilationUnit*         compiler;
+		llvm::InlineCostAnalysis costAnalysis;
+		unsigned int             inlineThreshold; 		// 225 in llvm
+		bool                     onlyAlwaysInline;
 
 		//FunctionInliner() : FunctionPass(ID) {}
-    FunctionInliner(CompilationUnit* _compiler, unsigned int _inlineThreshold=225) : FunctionPass(ID) { 
+    FunctionInliner(CompilationUnit* _compiler, unsigned int _inlineThreshold, bool _onlyAlwaysInline) : 
+			FunctionPass(ID) { 
 			compiler = _compiler;
 			inlineThreshold = _inlineThreshold; 
+			onlyAlwaysInline = _onlyAlwaysInline;
 		}
 
     virtual const char* getPassName() const {
@@ -45,13 +47,20 @@ namespace vmkit {
 #endif
 
 	bool FunctionInliner::runOnFunction(llvm::Function& function) {
-		bool Changed = false;
+		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;
+
+			for(llvm::BasicBlock::iterator it=bb->begin(), prev=0; it!=bb->end() && prof<42; prev=it++) {
+				llvm::Instruction *insn = it;
 
-			for(llvm::BasicBlock::iterator it=bb->begin(); it!=bb->end();) {
-				llvm::Instruction *insn = it++;
+				//fprintf(stderr, "  process: ");
+				//insn->dump();
 
 				if (insn->getOpcode() != llvm::Instruction::Call &&
 						insn->getOpcode() != llvm::Instruction::Invoke) {
@@ -59,47 +68,75 @@ namespace vmkit {
 				}
 
 				llvm::CallSite  call(insn);
-				llvm::Function* original = call.getCalledFunction();
-				llvm::Function* callee = original;
+				llvm::Function* callee = call.getCalledFunction();
 
 				if(!callee)
 					continue;
 
+				llvm::Function* bc = callee;
+
 				if(callee->isDeclaration()) { /* ok, resolve */
-					Symbol* s = compiler->getSymbol(callee->getName().data(), 0);
+					if(callee->isMaterializable())
+						callee->Materialize();
+
+					if(callee->isDeclaration()) {
+						Symbol* s = compiler->getSymbol(bc->getName().data(), 0);
 					
-					if(s && s->isInlinable())
-						callee = s->llvmFunction();
+						if(s && s->isInlinable())
+							bc = s->llvmFunction();
+					}
 				}
 
-				if(callee && !callee->isDeclaration()) {
-					llvm::InlineCost cost = getInlineCost(call, callee);
-					if(cost.isAlways()) {// || (!cost.isNever() && (cost))) {
-						//fprintf(stderr, "----   Inlining: %s\n", callee->getName().data());
+				/* 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;
+				}
 
+				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(cost.isAlways()) {// || (!onlyAlwaysInline && !cost.isNever() && cost)) {
+						if(bc != callee)
+							callee->replaceAllUsesWith(bc);
+						
 						llvm::InlineFunctionInfo ifi(0);
 						bool isInlined = llvm::InlineFunction(call, ifi, false);
 						Changed |= isInlined;
 
-						if(isInlined){
-							it = bb->begin();
-							continue;
+						if(isInlined) {
+							//							prof++;
+							//							it = prev ? prev : bb->begin();
+							//							continue;
+							goto restart;
 						}
 					}
 				}
-
-				if(original->getParent() != function.getParent()) {
-					callee = (llvm::Function*)function.getParent()->getOrInsertFunction(original->getName(), original->getFunctionType());
-					original->replaceAllUsesWith(callee);
-					Changed = 1;
-				}
 			}
 		}
 
+		//function.dump();
+
 		return Changed;
 	}
 
-	llvm::FunctionPass* createFunctionInlinerPass(CompilationUnit* compiler) {
-		return new FunctionInliner(compiler);
+	llvm::FunctionPass* createFunctionInlinerPass(CompilationUnit* compiler, bool onlyAlwaysInline) {
+		return new FunctionInliner(compiler, 2, onlyAlwaysInline);
 	}
 }

Modified: vmkit/branches/mcjit/tools/vmkit-extract/main.cc
URL: http://llvm.org/viewvc/llvm-project/vmkit/branches/mcjit/tools/vmkit-extract/main.cc?rev=199849&r1=199848&r2=199849&view=diff
==============================================================================
--- vmkit/branches/mcjit/tools/vmkit-extract/main.cc (original)
+++ vmkit/branches/mcjit/tools/vmkit-extract/main.cc Wed Jan 22 17:05:38 2014
@@ -57,8 +57,16 @@ int main(int argc, char** argv) {
 	char* buf;
 
 	while(getline(&buf, &linecapp, fp) > 0) { 
-		char* p = strchr(buf, '"') + 1;
-		char* e = strchr(p, '"');
+		char* p = strchr(buf, '"');
+		
+		if(!p)
+			continue;
+
+		char* e = strchr(++p, '"');
+
+		if(!e)
+			continue;
+
 		*e = 0;
 		llvm::GlobalValue* gv = mangler[p];
 





More information about the vmkit-commits mailing list