--- a/hotspot/src/share/vm/opto/cfgnode.hpp Fri Jan 09 09:52:00 2015 +0100
+++ b/hotspot/src/share/vm/opto/cfgnode.hpp Fri Jan 09 09:06:24 2015 +0000
@@ -361,22 +361,36 @@
#endif
};
-class IfTrueNode : public CProjNode {
+class IfProjNode : public CProjNode {
public:
- IfTrueNode( IfNode *ifnode ) : CProjNode(ifnode,1) {
+ IfProjNode(IfNode *ifnode, uint idx) : CProjNode(ifnode,idx) {}
+ virtual Node *Identity(PhaseTransform *phase);
+
+protected:
+ // Type of If input when this branch is always taken
+ virtual bool always_taken(const TypeTuple* t) const = 0;
+};
+
+class IfTrueNode : public IfProjNode {
+public:
+ IfTrueNode( IfNode *ifnode ) : IfProjNode(ifnode,1) {
init_class_id(Class_IfTrue);
}
virtual int Opcode() const;
- virtual Node *Identity( PhaseTransform *phase );
+
+protected:
+ virtual bool always_taken(const TypeTuple* t) const { return t == TypeTuple::IFTRUE; }
};
-class IfFalseNode : public CProjNode {
+class IfFalseNode : public IfProjNode {
public:
- IfFalseNode( IfNode *ifnode ) : CProjNode(ifnode,0) {
+ IfFalseNode( IfNode *ifnode ) : IfProjNode(ifnode,0) {
init_class_id(Class_IfFalse);
}
virtual int Opcode() const;
- virtual Node *Identity( PhaseTransform *phase );
+
+protected:
+ virtual bool always_taken(const TypeTuple* t) const { return t == TypeTuple::IFFALSE; }
};
--- a/hotspot/src/share/vm/opto/ifnode.cpp Fri Jan 09 09:52:00 2015 +0100
+++ b/hotspot/src/share/vm/opto/ifnode.cpp Fri Jan 09 09:06:24 2015 +0000
@@ -1122,12 +1122,21 @@
//------------------------------Identity---------------------------------------
// If the test is constant & we match, then we are the input Control
-Node *IfTrueNode::Identity( PhaseTransform *phase ) {
+Node *IfProjNode::Identity(PhaseTransform *phase) {
// Can only optimize if cannot go the other way
const TypeTuple *t = phase->type(in(0))->is_tuple();
- return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFTRUE )
- ? in(0)->in(0) // IfNode control
- : this; // no progress
+ if (t == TypeTuple::IFNEITHER ||
+ // kill dead branch first otherwise the IfNode's control will
+ // have 2 control uses (the IfNode that doesn't go away because
+ // it still has uses and this branch of the
+ // If). Node::has_special_unique_user() will cause this node to
+ // be reprocessed once the dead branch is killed.
+ (always_taken(t) && in(0)->outcnt() == 1)) {
+ // IfNode control
+ return in(0)->in(0);
+ }
+ // no progress
+ return this;
}
//------------------------------dump_spec--------------------------------------
@@ -1195,13 +1204,3 @@
// Progress
return iff;
}
-
-//------------------------------Identity---------------------------------------
-// If the test is constant & we match, then we are the input Control
-Node *IfFalseNode::Identity( PhaseTransform *phase ) {
- // Can only optimize if cannot go the other way
- const TypeTuple *t = phase->type(in(0))->is_tuple();
- return ( t == TypeTuple::IFNEITHER || t == TypeTuple::IFFALSE )
- ? in(0)->in(0) // IfNode control
- : this; // no progress
-}
--- a/hotspot/src/share/vm/opto/node.cpp Fri Jan 09 09:52:00 2015 +0100
+++ b/hotspot/src/share/vm/opto/node.cpp Fri Jan 09 09:06:24 2015 +0000
@@ -1080,18 +1080,21 @@
assert(outcnt() == 1, "match only for unique out");
Node* n = unique_out();
int op = Opcode();
- if( this->is_Store() ) {
+ if (this->is_Store()) {
// Condition for back-to-back stores folding.
return n->Opcode() == op && n->in(MemNode::Memory) == this;
} else if (this->is_Load()) {
// Condition for removing an unused LoadNode from the MemBarAcquire precedence input
return n->Opcode() == Op_MemBarAcquire;
- } else if( op == Op_AddL ) {
+ } else if (op == Op_AddL) {
// Condition for convL2I(addL(x,y)) ==> addI(convL2I(x),convL2I(y))
return n->Opcode() == Op_ConvL2I && n->in(1) == this;
- } else if( op == Op_SubI || op == Op_SubL ) {
+ } else if (op == Op_SubI || op == Op_SubL) {
// Condition for subI(x,subI(y,z)) ==> subI(addI(x,z),y)
return n->Opcode() == op && n->in(2) == this;
+ } else if (is_If() && (n->is_IfFalse() || n->is_IfTrue())) {
+ // See IfProjNode::Identity()
+ return true;
}
return false;
};