avoid generating unreachable code after tail calls

This commit is contained in:
Joel Dice 2009-04-25 20:54:36 -06:00
parent bf8fdb6316
commit 64b529c915
3 changed files with 20 additions and 13 deletions

View File

@ -1952,9 +1952,9 @@ compileDirectInvoke(MyThread* t, Frame* frame, object target, bool tailCall,
difference(&(t->tailAddress), t))); difference(&(t->tailAddress), t)));
if (methodFlags(t, target) & ACC_NATIVE) { if (methodFlags(t, target) & ACC_NATIVE) {
c->jmp(c->constant(nativeThunk(t))); c->exit(c->constant(nativeThunk(t)));
} else { } else {
c->jmp(c->constant(defaultThunk(t))); c->exit(c->constant(defaultThunk(t)));
} }
return result; return result;

View File

@ -620,7 +620,7 @@ class Event {
virtual bool isBranch() { return false; } virtual bool isBranch() { return false; }
virtual bool allTailCalls() { return false; } virtual bool allExits() { return false; }
Event* next; Event* next;
Stack* stackBefore; Stack* stackBefore;
@ -2535,7 +2535,7 @@ class CallEvent: public Event {
} }
} }
virtual bool allTailCalls() { virtual bool allExits() {
return (flags & Compiler::TailJump) != 0; return (flags & Compiler::TailJump) != 0;
} }
@ -2565,10 +2565,10 @@ appendCall(Context* c, Value* address, unsigned flags,
} }
bool bool
followsOnlyTailCalls(Event* event) unreachable(Event* event)
{ {
for (Link* p = event->predecessors; p; p = p->nextPredecessor) { for (Link* p = event->predecessors; p; p = p->nextPredecessor) {
if (not p->predecessor->allTailCalls()) return false; if (not p->predecessor->allExits()) return false;
} }
return true; return true;
} }
@ -2596,7 +2596,7 @@ class ReturnEvent: public Event {
popRead(c, this, r->value); popRead(c, this, r->value);
} }
if (not followsOnlyTailCalls(this)) { if (not unreachable(this)) {
c->assembler->popFrameAndPopArgumentsAndReturn c->assembler->popFrameAndPopArgumentsAndReturn
(c->arch->argumentFootprint(c->parameterFootprint)); (c->arch->argumentFootprint(c->parameterFootprint));
} }
@ -3692,8 +3692,8 @@ appendMemory(Context* c, Value* base, int displacement, Value* index,
class BranchEvent: public Event { class BranchEvent: public Event {
public: public:
BranchEvent(Context* c, UnaryOperation type, Value* address): BranchEvent(Context* c, UnaryOperation type, Value* address, bool exit):
Event(c), type(type), address(address) Event(c), type(type), address(address), exit(exit)
{ {
address->addPredecessor(c, this); address->addPredecessor(c, this);
@ -3779,19 +3779,21 @@ class BranchEvent: public Event {
virtual bool isBranch() { return true; } virtual bool isBranch() { return true; }
virtual bool allTailCalls() { virtual bool allExits() {
return type == Jump and followsOnlyTailCalls(this); return type == Jump and (exit or unreachable(this));
} }
UnaryOperation type; UnaryOperation type;
Value* address; Value* address;
bool exit;
}; };
void void
appendBranch(Context* c, UnaryOperation type, Value* address) appendBranch(Context* c, UnaryOperation type, Value* address,
bool exit = false)
{ {
append(c, new (c->zone->allocate(sizeof(BranchEvent))) append(c, new (c->zone->allocate(sizeof(BranchEvent)))
BranchEvent(c, type, address)); BranchEvent(c, type, address, exit));
} }
class BoundsCheckEvent: public Event { class BoundsCheckEvent: public Event {
@ -5465,6 +5467,10 @@ class MyCompiler: public Compiler {
appendBranch(&c, Jump, static_cast<Value*>(address)); appendBranch(&c, Jump, static_cast<Value*>(address));
} }
virtual void exit(Operand* address) {
appendBranch(&c, Jump, static_cast<Value*>(address), true);
}
virtual Operand* add(unsigned size, Operand* a, Operand* b) { virtual Operand* add(unsigned size, Operand* a, Operand* b) {
Value* result = value(&c); Value* result = value(&c);
appendCombine(&c, Add, size, static_cast<Value*>(a), appendCombine(&c, Add, size, static_cast<Value*>(a),

View File

@ -116,6 +116,7 @@ class Compiler {
virtual void je(Operand* address) = 0; virtual void je(Operand* address) = 0;
virtual void jne(Operand* address) = 0; virtual void jne(Operand* address) = 0;
virtual void jmp(Operand* address) = 0; virtual void jmp(Operand* address) = 0;
virtual void exit(Operand* address) = 0;
virtual Operand* add(unsigned size, Operand* a, Operand* b) = 0; virtual Operand* add(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* sub(unsigned size, Operand* a, Operand* b) = 0; virtual Operand* sub(unsigned size, Operand* a, Operand* b) = 0;
virtual Operand* mul(unsigned size, Operand* a, Operand* b) = 0; virtual Operand* mul(unsigned size, Operand* a, Operand* b) = 0;