[vmkit-commits] [vmkit] r67514 - /vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp
Nicolas Geoffray
nicolas.geoffray at lip6.fr
Mon Mar 23 02:01:24 PDT 2009
Author: geoffray
Date: Mon Mar 23 04:01:10 2009
New Revision: 67514
URL: http://llvm.org/viewvc/llvm-project?rev=67514&view=rev
Log:
Allow Escape analysis to run when compiling AOT. Useless for objects for now
because the <init> function is in the way, not being inlined.
Modified:
vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp
Modified: vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp?rev=67514&r1=67513&r2=67514&view=diff
==============================================================================
--- vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp (original)
+++ vmkit/trunk/lib/Mvm/Compiler/EscapeAnalysis.cpp Mon Mar 23 04:01:10 2009
@@ -9,8 +9,9 @@
#include "llvm/Constants.h"
-#include "llvm/Pass.h"
#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Pass.h"
#include "llvm/Instructions.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
@@ -67,12 +68,16 @@
-static bool escapes(Instruction* Ins, std::map<Instruction*, bool>& visited) {
+static bool escapes(Value* Ins, std::map<Instruction*, bool>& visited) {
for (Value::use_iterator I = Ins->use_begin(), E = Ins->use_end();
I != E; ++I) {
if (Instruction* II = dyn_cast<Instruction>(I)) {
- if (dyn_cast<CallInst>(II)) return true;
- else if (dyn_cast<InvokeInst>(II)) return true;
+ if (CallInst* CI = dyn_cast<CallInst>(II)) {
+ if (!CI->onlyReadsMemory()) return true;
+ }
+ else if (InvokeInst* CI = dyn_cast<InvokeInst>(II)) {
+ if (!CI->onlyReadsMemory()) return true;
+ }
else if (dyn_cast<BitCastInst>(II)) {
if (escapes(II, visited)) return true;
}
@@ -111,30 +116,46 @@
bool EscapeAnalysis::processMalloc(Instruction* I, Value* Size, Value* VT) {
Instruction* Alloc = I;
- ConstantExpr* CE = dyn_cast<ConstantExpr>(VT);
- if (CE) {
- ConstantInt* C = dyn_cast<ConstantInt>(CE->getOperand(0));
- if (!C) return false;
-
- VirtualTable* Table = (VirtualTable*)C->getZExtValue();
- ConstantInt* CI = dyn_cast<ConstantInt>(Size);
- // If the class has a finalize method, do not stack allocate the object.
- if (!((void**)Table)[0] && CI) {
- std::map<Instruction*, bool> visited;
- uint64_t NSize = CI->getZExtValue();
- if (NSize < pageSize && !(escapes(Alloc, visited))) {
- AllocaInst* AI = new AllocaInst(Type::Int8Ty, Size, "", Alloc);
- BitCastInst* BI = new BitCastInst(AI, Alloc->getType(), "", Alloc);
- DOUT << "escape" << Alloc->getParent()->getParent()->getName() << "\n";
- Alloc->replaceAllUsesWith(BI);
- // If it's an invoke, replace the invoke with a direct branch.
- if (InvokeInst *CI = dyn_cast<InvokeInst>(Alloc)) {
- BranchInst::Create(CI->getNormalDest(), Alloc);
+ ConstantInt* CI = dyn_cast<ConstantInt>(Size);
+ bool hasFinalizer = true;
+
+ if (CI) {
+ if (ConstantExpr* CE = dyn_cast<ConstantExpr>(VT)) {
+ if (ConstantInt* C = dyn_cast<ConstantInt>(CE->getOperand(0))) {
+ VirtualTable* Table = (VirtualTable*)C->getZExtValue();
+ hasFinalizer = (((void**)Table)[0] != 0);
+ } else {
+ GlobalVariable* GV = dyn_cast<GlobalVariable>(CE->getOperand(0));
+ if (GV->hasInitializer()) {
+ Constant* Init = GV->getInitializer();
+ if (ConstantArray* CA = dyn_cast<ConstantArray>(Init)) {
+ Constant* V = CA->getOperand(0);
+ hasFinalizer = !V->isNullValue();
+ }
}
- Alloc->eraseFromParent();
- return true;
}
}
+ } else {
+ return false;
+ }
+
+ uint64_t NSize = CI->getZExtValue();
+ // If the class has a finalize method, do not stack allocate the object.
+ if (NSize < pageSize && !hasFinalizer) {
+ std::map<Instruction*, bool> visited;
+ bool esc = escapes(Alloc, visited);
+ if (!esc) {
+ AllocaInst* AI = new AllocaInst(Type::Int8Ty, Size, "", Alloc);
+ BitCastInst* BI = new BitCastInst(AI, Alloc->getType(), "", Alloc);
+ DOUT << "escape" << Alloc->getParent()->getParent()->getName() << "\n";
+ Alloc->replaceAllUsesWith(BI);
+ // If it's an invoke, replace the invoke with a direct branch.
+ if (InvokeInst *CI = dyn_cast<InvokeInst>(Alloc)) {
+ BranchInst::Create(CI->getNormalDest(), Alloc);
+ }
+ Alloc->eraseFromParent();
+ return true;
+ }
}
return false;
}
More information about the vmkit-commits
mailing list