[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