mirror of
https://github.com/corda/corda.git
synced 2025-01-08 14:03:06 +00:00
avoid generating unreachable code after tail calls
This commit is contained in:
parent
bf8fdb6316
commit
64b529c915
@ -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;
|
||||||
|
@ -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),
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user