提交 e4ccd055 编写于 作者: N never

Merge

...@@ -36,6 +36,7 @@ public class Database { ...@@ -36,6 +36,7 @@ public class Database {
private FileList outerFiles; private FileList outerFiles;
private FileList indivIncludes; private FileList indivIncludes;
private FileList grandInclude; // the results for the grand include file private FileList grandInclude; // the results for the grand include file
private HashMap<String,String> platformDepFiles;
private long threshold; private long threshold;
private int nOuterFiles; private int nOuterFiles;
private int nPrecompiledFiles; private int nPrecompiledFiles;
...@@ -57,6 +58,7 @@ public class Database { ...@@ -57,6 +58,7 @@ public class Database {
outerFiles = new FileList("outerFiles", plat); outerFiles = new FileList("outerFiles", plat);
indivIncludes = new FileList("IndivIncludes", plat); indivIncludes = new FileList("IndivIncludes", plat);
grandInclude = new FileList(plat.getGIFileTemplate().nameOfList(), plat); grandInclude = new FileList(plat.getGIFileTemplate().nameOfList(), plat);
platformDepFiles = new HashMap<String,String>();
threshold = t; threshold = t;
nOuterFiles = 0; nOuterFiles = 0;
...@@ -209,6 +211,10 @@ public class Database { ...@@ -209,6 +211,10 @@ public class Database {
FileList p = allFiles.listForFile(includer); FileList p = allFiles.listForFile(includer);
p.setPlatformDependentInclude(pdName.dirPreStemSuff()); p.setPlatformDependentInclude(pdName.dirPreStemSuff());
// Record the implicit include of this file so that the
// dependencies for precompiled headers can mention it.
platformDepFiles.put(newIncluder, includer);
// Add an implicit dependency on platform // Add an implicit dependency on platform
// specific file for the generic file // specific file for the generic file
...@@ -408,6 +414,12 @@ public class Database { ...@@ -408,6 +414,12 @@ public class Database {
for (Iterator iter = grandInclude.iterator(); iter.hasNext(); ) { for (Iterator iter = grandInclude.iterator(); iter.hasNext(); ) {
FileList list = (FileList) iter.next(); FileList list = (FileList) iter.next();
gd.println(list.getName() + " \\"); gd.println(list.getName() + " \\");
String platformDep = platformDepFiles.get(list.getName());
if (platformDep != null) {
// make sure changes to the platform dependent file will
// cause regeneration of the pch file.
gd.println(platformDep + " \\");
}
} }
gd.println(); gd.println();
gd.println(); gd.println();
......
...@@ -729,6 +729,7 @@ bool InstructForm::captures_bottom_type() const { ...@@ -729,6 +729,7 @@ bool InstructForm::captures_bottom_type() const {
!strcmp(_matrule->_rChild->_opType,"DecodeN") || !strcmp(_matrule->_rChild->_opType,"DecodeN") ||
!strcmp(_matrule->_rChild->_opType,"EncodeP") || !strcmp(_matrule->_rChild->_opType,"EncodeP") ||
!strcmp(_matrule->_rChild->_opType,"LoadN") || !strcmp(_matrule->_rChild->_opType,"LoadN") ||
!strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||
!strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception !strcmp(_matrule->_rChild->_opType,"CreateEx") || // type of exception
!strcmp(_matrule->_rChild->_opType,"CheckCastPP")) ) return true; !strcmp(_matrule->_rChild->_opType,"CheckCastPP")) ) return true;
else if ( is_ideal_load() == Form::idealP ) return true; else if ( is_ideal_load() == Form::idealP ) return true;
......
...@@ -565,10 +565,12 @@ Node* DecodeNNode::Identity(PhaseTransform* phase) { ...@@ -565,10 +565,12 @@ Node* DecodeNNode::Identity(PhaseTransform* phase) {
} }
const Type *DecodeNNode::Value( PhaseTransform *phase ) const { const Type *DecodeNNode::Value( PhaseTransform *phase ) const {
if (phase->type( in(1) ) == TypeNarrowOop::NULL_PTR) { const Type *t = phase->type( in(1) );
return TypePtr::NULL_PTR; if (t == Type::TOP) return Type::TOP;
} if (t == TypeNarrowOop::NULL_PTR) return TypePtr::NULL_PTR;
return bottom_type();
assert(t->isa_narrowoop(), "only narrowoop here");
return t->is_narrowoop()->make_oopptr();
} }
Node* DecodeNNode::decode(PhaseTransform* phase, Node* value) { Node* DecodeNNode::decode(PhaseTransform* phase, Node* value) {
...@@ -599,10 +601,12 @@ Node* EncodePNode::Identity(PhaseTransform* phase) { ...@@ -599,10 +601,12 @@ Node* EncodePNode::Identity(PhaseTransform* phase) {
} }
const Type *EncodePNode::Value( PhaseTransform *phase ) const { const Type *EncodePNode::Value( PhaseTransform *phase ) const {
if (phase->type( in(1) ) == TypePtr::NULL_PTR) { const Type *t = phase->type( in(1) );
return TypeNarrowOop::NULL_PTR; if (t == Type::TOP) return Type::TOP;
} if (t == TypePtr::NULL_PTR) return TypeNarrowOop::NULL_PTR;
return bottom_type();
assert(t->isa_oopptr(), "only oopptr here");
return t->is_oopptr()->make_narrowoop();
} }
Node* EncodePNode::encode(PhaseTransform* phase, Node* value) { Node* EncodePNode::encode(PhaseTransform* phase, Node* value) {
......
...@@ -549,10 +549,18 @@ class Opaque1Node : public Node { ...@@ -549,10 +549,18 @@ class Opaque1Node : public Node {
virtual uint hash() const ; // { return NO_HASH; } virtual uint hash() const ; // { return NO_HASH; }
virtual uint cmp( const Node &n ) const; virtual uint cmp( const Node &n ) const;
public: public:
Opaque1Node( Node *n ) : Node(0,n) {} Opaque1Node( Compile* C, Node *n ) : Node(0,n) {
// Put it on the Macro nodes list to removed during macro nodes expansion.
init_flags(Flag_is_macro);
C->add_macro_node(this);
}
// Special version for the pre-loop to hold the original loop limit // Special version for the pre-loop to hold the original loop limit
// which is consumed by range check elimination. // which is consumed by range check elimination.
Opaque1Node( Node *n, Node* orig_limit ) : Node(0,n,orig_limit) {} Opaque1Node( Compile* C, Node *n, Node* orig_limit ) : Node(0,n,orig_limit) {
// Put it on the Macro nodes list to removed during macro nodes expansion.
init_flags(Flag_is_macro);
C->add_macro_node(this);
}
Node* original_loop_limit() { return req()==3 ? in(2) : NULL; } Node* original_loop_limit() { return req()==3 ? in(2) : NULL; }
virtual int Opcode() const; virtual int Opcode() const;
virtual const Type *bottom_type() const { return TypeInt::INT; } virtual const Type *bottom_type() const { return TypeInt::INT; }
...@@ -572,7 +580,11 @@ class Opaque2Node : public Node { ...@@ -572,7 +580,11 @@ class Opaque2Node : public Node {
virtual uint hash() const ; // { return NO_HASH; } virtual uint hash() const ; // { return NO_HASH; }
virtual uint cmp( const Node &n ) const; virtual uint cmp( const Node &n ) const;
public: public:
Opaque2Node( Node *n ) : Node(0,n) {} Opaque2Node( Compile* C, Node *n ) : Node(0,n) {
// Put it on the Macro nodes list to removed during macro nodes expansion.
init_flags(Flag_is_macro);
C->add_macro_node(this);
}
virtual int Opcode() const; virtual int Opcode() const;
virtual const Type *bottom_type() const { return TypeInt::INT; } virtual const Type *bottom_type() const { return TypeInt::INT; }
}; };
......
...@@ -307,7 +307,6 @@ static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark, ...@@ -307,7 +307,6 @@ static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark,
// Test and set the visited bit. // Test and set the visited bit.
if (mid->raise_LCA_visited() == mark) continue; // already visited if (mid->raise_LCA_visited() == mark) continue; // already visited
mid->set_raise_LCA_visited(mark);
// Don't process the current LCA, otherwise the search may terminate early // Don't process the current LCA, otherwise the search may terminate early
if (mid != LCA && mid->raise_LCA_mark() == mark) { if (mid != LCA && mid->raise_LCA_mark() == mark) {
...@@ -317,6 +316,8 @@ static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark, ...@@ -317,6 +316,8 @@ static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark,
assert(early->dominates(LCA), "early is high enough"); assert(early->dominates(LCA), "early is high enough");
// Resume searching at that point, skipping intermediate levels. // Resume searching at that point, skipping intermediate levels.
worklist.push(LCA); worklist.push(LCA);
if (LCA == mid)
continue; // Don't mark as visited to avoid early termination.
} else { } else {
// Keep searching through this block's predecessors. // Keep searching through this block's predecessors.
for (uint j = 1, jmax = mid->num_preds(); j < jmax; j++) { for (uint j = 1, jmax = mid->num_preds(); j < jmax; j++) {
...@@ -324,6 +325,7 @@ static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark, ...@@ -324,6 +325,7 @@ static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark,
worklist.push(mid_parent); worklist.push(mid_parent);
} }
} }
mid->set_raise_LCA_visited(mark);
} }
return LCA; return LCA;
} }
......
...@@ -690,7 +690,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_ ...@@ -690,7 +690,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
// (the main-loop trip-counter exit value) because we will be changing // (the main-loop trip-counter exit value) because we will be changing
// the exit value (via unrolling) so we cannot constant-fold away the zero // the exit value (via unrolling) so we cannot constant-fold away the zero
// trip guard until all unrolling is done. // trip guard until all unrolling is done.
Node *zer_opaq = new (C, 2) Opaque1Node(incr); Node *zer_opaq = new (C, 2) Opaque1Node(C, incr);
Node *zer_cmp = new (C, 3) CmpINode( zer_opaq, limit ); Node *zer_cmp = new (C, 3) CmpINode( zer_opaq, limit );
Node *zer_bol = new (C, 2) BoolNode( zer_cmp, b_test ); Node *zer_bol = new (C, 2) BoolNode( zer_cmp, b_test );
register_new_node( zer_opaq, new_main_exit ); register_new_node( zer_opaq, new_main_exit );
...@@ -760,7 +760,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_ ...@@ -760,7 +760,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
// pre-loop, the main-loop may not execute at all. Later in life this // pre-loop, the main-loop may not execute at all. Later in life this
// zero-trip guard will become the minimum-trip guard when we unroll // zero-trip guard will become the minimum-trip guard when we unroll
// the main-loop. // the main-loop.
Node *min_opaq = new (C, 2) Opaque1Node(limit); Node *min_opaq = new (C, 2) Opaque1Node(C, limit);
Node *min_cmp = new (C, 3) CmpINode( pre_incr, min_opaq ); Node *min_cmp = new (C, 3) CmpINode( pre_incr, min_opaq );
Node *min_bol = new (C, 2) BoolNode( min_cmp, b_test ); Node *min_bol = new (C, 2) BoolNode( min_cmp, b_test );
register_new_node( min_opaq, new_pre_exit ); register_new_node( min_opaq, new_pre_exit );
...@@ -810,7 +810,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_ ...@@ -810,7 +810,7 @@ void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_
// Save the original loop limit in this Opaque1 node for // Save the original loop limit in this Opaque1 node for
// use by range check elimination. // use by range check elimination.
Node *pre_opaq = new (C, 3) Opaque1Node(pre_limit, limit); Node *pre_opaq = new (C, 3) Opaque1Node(C, pre_limit, limit);
register_new_node( pre_limit, pre_head->in(0) ); register_new_node( pre_limit, pre_head->in(0) );
register_new_node( pre_opaq , pre_head->in(0) ); register_new_node( pre_opaq , pre_head->in(0) );
......
...@@ -205,7 +205,7 @@ ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop, ...@@ -205,7 +205,7 @@ ProjNode* PhaseIdealLoop::create_slow_version_of_loop(IdealLoopTree *loop,
Node *cont = _igvn.intcon(1); Node *cont = _igvn.intcon(1);
set_ctrl(cont, C->root()); set_ctrl(cont, C->root());
Node* opq = new (C, 2) Opaque1Node(cont); Node* opq = new (C, 2) Opaque1Node(C, cont);
register_node(opq, outer_loop, entry, dom_depth(entry)); register_node(opq, outer_loop, entry, dom_depth(entry));
Node *bol = new (C, 2) Conv2BNode(opq); Node *bol = new (C, 2) Conv2BNode(opq);
register_node(bol, outer_loop, entry, dom_depth(entry)); register_node(bol, outer_loop, entry, dom_depth(entry));
......
...@@ -2685,7 +2685,7 @@ void PhaseIdealLoop::reorg_offsets( IdealLoopTree *loop ) { ...@@ -2685,7 +2685,7 @@ void PhaseIdealLoop::reorg_offsets( IdealLoopTree *loop ) {
if( !cle->stride_is_con() ) continue; if( !cle->stride_is_con() ) continue;
// Hit! Refactor use to use the post-incremented tripcounter. // Hit! Refactor use to use the post-incremented tripcounter.
// Compute a post-increment tripcounter. // Compute a post-increment tripcounter.
Node *opaq = new (C, 2) Opaque2Node( cle->incr() ); Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() );
register_new_node( opaq, u_ctrl ); register_new_node( opaq, u_ctrl );
Node *neg_stride = _igvn.intcon(-cle->stride_con()); Node *neg_stride = _igvn.intcon(-cle->stride_con());
set_ctrl(neg_stride, C->root()); set_ctrl(neg_stride, C->root());
......
...@@ -262,14 +262,16 @@ const Node* MachNode::get_base_and_disp(intptr_t &offset, const TypePtr* &adr_ty ...@@ -262,14 +262,16 @@ const Node* MachNode::get_base_and_disp(intptr_t &offset, const TypePtr* &adr_ty
// Now we have collected every part of the ADLC MEMORY_INTER. // Now we have collected every part of the ADLC MEMORY_INTER.
// See if it adds up to a base + offset. // See if it adds up to a base + offset.
if (index != NULL) { if (index != NULL) {
if (!index->is_Con()) { const TypeNarrowOop* narrowoop = index->bottom_type()->isa_narrowoop();
const TypeNarrowOop* narrowoop = index->bottom_type()->isa_narrowoop(); if (narrowoop != NULL) { // EncodeN, LoadN, LoadConN, LoadNKlass.
if (narrowoop != NULL) { // Memory references through narrow oops have a
// Memory references through narrow oops have a // funny base so grab the type from the index:
// funny base so grab the type from the index. // [R12 + narrow_oop_reg<<3 + offset]
adr_type = narrowoop->make_oopptr(); assert(base == NULL, "Memory references through narrow oops have no base");
return NULL; offset = disp;
} adr_type = narrowoop->make_oopptr()->add_offset(offset);
return NULL;
} else if (!index->is_Con()) {
disp = Type::OffsetBot; disp = Type::OffsetBot;
} else if (disp != Type::OffsetBot) { } else if (disp != Type::OffsetBot) {
const TypeX* ti = index->bottom_type()->isa_intptr_t(); const TypeX* ti = index->bottom_type()->isa_intptr_t();
......
...@@ -1674,7 +1674,14 @@ bool PhaseMacroExpand::expand_macro_nodes() { ...@@ -1674,7 +1674,14 @@ bool PhaseMacroExpand::expand_macro_nodes() {
success = eliminate_locking_node(n->as_AbstractLock()); success = eliminate_locking_node(n->as_AbstractLock());
break; break;
default: default:
assert(false, "unknown node type in macro list"); if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
_igvn.add_users_to_worklist(n);
_igvn.hash_delete(n);
_igvn.subsume_node(n, n->in(1));
success = true;
} else {
assert(false, "unknown node type in macro list");
}
} }
assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
progress = progress || success; progress = progress || success;
......
...@@ -82,6 +82,7 @@ Matcher::Matcher( Node_List &proj_list ) : ...@@ -82,6 +82,7 @@ Matcher::Matcher( Node_List &proj_list ) :
idealreg2debugmask[Op_RegF] = NULL; idealreg2debugmask[Op_RegF] = NULL;
idealreg2debugmask[Op_RegD] = NULL; idealreg2debugmask[Op_RegD] = NULL;
idealreg2debugmask[Op_RegP] = NULL; idealreg2debugmask[Op_RegP] = NULL;
debug_only(_mem_node = NULL;) // Ideal memory node consumed by mach node
} }
//------------------------------warp_incoming_stk_arg------------------------ //------------------------------warp_incoming_stk_arg------------------------
...@@ -1153,7 +1154,10 @@ MachNode *Matcher::match_tree( const Node *n ) { ...@@ -1153,7 +1154,10 @@ MachNode *Matcher::match_tree( const Node *n ) {
// StoreNodes require their Memory input to match any LoadNodes // StoreNodes require their Memory input to match any LoadNodes
Node *mem = n->is_Store() ? n->in(MemNode::Memory) : (Node*)1 ; Node *mem = n->is_Store() ? n->in(MemNode::Memory) : (Node*)1 ;
#ifdef ASSERT
Node* save_mem_node = _mem_node;
_mem_node = n->is_Store() ? (Node*)n : NULL;
#endif
// State object for root node of match tree // State object for root node of match tree
// Allocate it on _states_arena - stack allocation can cause stack overflow. // Allocate it on _states_arena - stack allocation can cause stack overflow.
State *s = new (&_states_arena) State; State *s = new (&_states_arena) State;
...@@ -1205,6 +1209,7 @@ MachNode *Matcher::match_tree( const Node *n ) { ...@@ -1205,6 +1209,7 @@ MachNode *Matcher::match_tree( const Node *n ) {
} }
} }
debug_only( _mem_node = save_mem_node; )
return m; return m;
} }
...@@ -1445,8 +1450,30 @@ MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) { ...@@ -1445,8 +1450,30 @@ MachNode *Matcher::ReduceInst( State *s, int rule, Node *&mem ) {
} }
// If a Memory was used, insert a Memory edge // If a Memory was used, insert a Memory edge
if( mem != (Node*)1 ) if( mem != (Node*)1 ) {
mach->ins_req(MemNode::Memory,mem); mach->ins_req(MemNode::Memory,mem);
#ifdef ASSERT
// Verify adr type after matching memory operation
const MachOper* oper = mach->memory_operand();
if (oper != NULL && oper != (MachOper*)-1 &&
mach->adr_type() != TypeRawPtr::BOTTOM) { // non-direct addressing mode
// It has a unique memory operand. Find corresponding ideal mem node.
Node* m = NULL;
if (leaf->is_Mem()) {
m = leaf;
} else {
m = _mem_node;
assert(m != NULL && m->is_Mem(), "expecting memory node");
}
if (m->adr_type() != mach->adr_type()) {
m->dump();
tty->print_cr("mach:");
mach->dump(1);
}
assert(m->adr_type() == mach->adr_type(), "matcher should not change adr type");
}
#endif
}
// If the _leaf is an AddP, insert the base edge // If the _leaf is an AddP, insert the base edge
if( leaf->is_AddP() ) if( leaf->is_AddP() )
...@@ -1510,7 +1537,9 @@ void Matcher::ReduceInst_Chain_Rule( State *s, int rule, Node *&mem, MachNode *m ...@@ -1510,7 +1537,9 @@ void Matcher::ReduceInst_Chain_Rule( State *s, int rule, Node *&mem, MachNode *m
assert( newrule >= _LAST_MACH_OPER, "Do NOT chain from internal operand"); assert( newrule >= _LAST_MACH_OPER, "Do NOT chain from internal operand");
mach->_opnds[1] = s->MachOperGenerator( _reduceOp[catch_op], C ); mach->_opnds[1] = s->MachOperGenerator( _reduceOp[catch_op], C );
Node *mem1 = (Node*)1; Node *mem1 = (Node*)1;
debug_only(Node *save_mem_node = _mem_node;)
mach->add_req( ReduceInst(s, newrule, mem1) ); mach->add_req( ReduceInst(s, newrule, mem1) );
debug_only(_mem_node = save_mem_node;)
} }
return; return;
} }
...@@ -1520,6 +1549,7 @@ uint Matcher::ReduceInst_Interior( State *s, int rule, Node *&mem, MachNode *mac ...@@ -1520,6 +1549,7 @@ uint Matcher::ReduceInst_Interior( State *s, int rule, Node *&mem, MachNode *mac
if( s->_leaf->is_Load() ) { if( s->_leaf->is_Load() ) {
Node *mem2 = s->_leaf->in(MemNode::Memory); Node *mem2 = s->_leaf->in(MemNode::Memory);
assert( mem == (Node*)1 || mem == mem2, "multiple Memories being matched at once?" ); assert( mem == (Node*)1 || mem == mem2, "multiple Memories being matched at once?" );
debug_only( if( mem == (Node*)1 ) _mem_node = s->_leaf;)
mem = mem2; mem = mem2;
} }
if( s->_leaf->in(0) != NULL && s->_leaf->req() > 1) { if( s->_leaf->in(0) != NULL && s->_leaf->req() > 1) {
...@@ -1563,7 +1593,9 @@ uint Matcher::ReduceInst_Interior( State *s, int rule, Node *&mem, MachNode *mac ...@@ -1563,7 +1593,9 @@ uint Matcher::ReduceInst_Interior( State *s, int rule, Node *&mem, MachNode *mac
// --> ReduceInst( newrule ) // --> ReduceInst( newrule )
mach->_opnds[num_opnds++] = s->MachOperGenerator( _reduceOp[catch_op], C ); mach->_opnds[num_opnds++] = s->MachOperGenerator( _reduceOp[catch_op], C );
Node *mem1 = (Node*)1; Node *mem1 = (Node*)1;
debug_only(Node *save_mem_node = _mem_node;)
mach->add_req( ReduceInst( newstate, newrule, mem1 ) ); mach->add_req( ReduceInst( newstate, newrule, mem1 ) );
debug_only(_mem_node = save_mem_node;)
} }
} }
assert( mach->_opnds[num_opnds-1], "" ); assert( mach->_opnds[num_opnds-1], "" );
...@@ -1594,6 +1626,7 @@ void Matcher::ReduceOper( State *s, int rule, Node *&mem, MachNode *mach ) { ...@@ -1594,6 +1626,7 @@ void Matcher::ReduceOper( State *s, int rule, Node *&mem, MachNode *mach ) {
if( s->_leaf->is_Load() ) { if( s->_leaf->is_Load() ) {
assert( mem == (Node*)1, "multiple Memories being matched at once?" ); assert( mem == (Node*)1, "multiple Memories being matched at once?" );
mem = s->_leaf->in(MemNode::Memory); mem = s->_leaf->in(MemNode::Memory);
debug_only(_mem_node = s->_leaf;)
} }
if( s->_leaf->in(0) && s->_leaf->req() > 1) { if( s->_leaf->in(0) && s->_leaf->req() > 1) {
if( !mach->in(0) ) if( !mach->in(0) )
...@@ -1618,7 +1651,9 @@ void Matcher::ReduceOper( State *s, int rule, Node *&mem, MachNode *mach ) { ...@@ -1618,7 +1651,9 @@ void Matcher::ReduceOper( State *s, int rule, Node *&mem, MachNode *mach ) {
// Reduce the instruction, and add a direct pointer from this // Reduce the instruction, and add a direct pointer from this
// machine instruction to the newly reduced one. // machine instruction to the newly reduced one.
Node *mem1 = (Node*)1; Node *mem1 = (Node*)1;
debug_only(Node *save_mem_node = _mem_node;)
mach->add_req( ReduceInst( kid, newrule, mem1 ) ); mach->add_req( ReduceInst( kid, newrule, mem1 ) );
debug_only(_mem_node = save_mem_node;)
} }
} }
} }
......
...@@ -104,6 +104,8 @@ class Matcher : public PhaseTransform { ...@@ -104,6 +104,8 @@ class Matcher : public PhaseTransform {
#ifdef ASSERT #ifdef ASSERT
// Make sure only new nodes are reachable from this node // Make sure only new nodes are reachable from this node
void verify_new_nodes_only(Node* root); void verify_new_nodes_only(Node* root);
Node* _mem_node; // Ideal memory node consumed by mach node
#endif #endif
public: public:
......
...@@ -45,10 +45,13 @@ Node *SubNode::Identity( PhaseTransform *phase ) { ...@@ -45,10 +45,13 @@ Node *SubNode::Identity( PhaseTransform *phase ) {
return in(2)->in(2); return in(2)->in(2);
} }
// Convert "(X+Y) - Y" into X // Convert "(X+Y) - Y" into X and "(X+Y) - X" into Y
if( in(1)->Opcode() == Op_AddI ) { if( in(1)->Opcode() == Op_AddI ) {
if( phase->eqv(in(1)->in(2),in(2)) ) if( phase->eqv(in(1)->in(2),in(2)) )
return in(1)->in(1); return in(1)->in(1);
if (phase->eqv(in(1)->in(1),in(2)))
return in(1)->in(2);
// Also catch: "(X + Opaque2(Y)) - Y". In this case, 'Y' is a loop-varying // Also catch: "(X + Opaque2(Y)) - Y". In this case, 'Y' is a loop-varying
// trip counter and X is likely to be loop-invariant (that's how O2 Nodes // trip counter and X is likely to be loop-invariant (that's how O2 Nodes
// are originally used, although the optimizer sometimes jiggers things). // are originally used, although the optimizer sometimes jiggers things).
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册