src/share/vm/opto/addnode.cpp
Print this page
*** 318,327 ****
--- 318,402 ----
return new (phase->C) URShiftINode( a, in1->in(2) );
}
}
}
+ // Converts the following tree to a loadI if loaded 4 bytes are contiguous.
+ //
+ // this:AddI
+ // |
+ // in1:AddI-------------+------------in2:LShiftI
+ // | |
+ // in3:AddI-------------+------------in4:LShiftI in5:LoadB--+--...
+ // | | |
+ // in6:AndI-----+-----in7:LShiftI in8:AndI--+--... mem
+ // | | |
+ // in9:loadB--+--... in10:AndI--+--... in11:LoadB--+--...
+ // | | |
+ // mem in12:LoadB mem
+ // |
+ // mem
+ //
+ if ( op1 == Op_AddI && op2 == Op_LShiftI ) {
+ Node *in3 = in1->in(1);
+ Node *in4 = in1->in(2);
+ Node *in5 = in2->in(1);
+ if ( in3->Opcode() == Op_AddI &&
+ in4->Opcode() == Op_LShiftI &&
+ in5->Opcode() == Op_LoadB ) {
+ Node *in6 = in3->in(1);
+ Node *in7 = in3->in(2);
+ Node *in8 = in4->in(1);
+ if ( in6->Opcode() == Op_AndI &&
+ in7->Opcode() == Op_LShiftI &&
+ in8->Opcode() == Op_AndI ) {
+ Node *in9 = in6->in(1);
+ Node *in10 = in7->in(1);
+ Node *in11 = in8->in(1);
+ if ( in9->Opcode() == Op_LoadB &&
+ in10->Opcode() == Op_AndI &&
+ in11->Opcode() == Op_LoadB ) {
+ Node *in12 = in10->in(1);
+ if ( in12->Opcode() == Op_LoadB ) {
+ LoadBNode *loadb1 = (LoadBNode *) in9;
+ Node *adr1 = loadb1->in(MemNode::Address);
+ Node *load1_base = adr1->in(1);
+ const TypePtr* tp1 = adr1->bottom_type()->isa_ptr();
+ int load1_offset = tp1->offset();
+
+ LoadBNode *loadb2 = (LoadBNode *) in12;
+ Node *adr2 = loadb2->in(MemNode::Address);
+ Node *load2_base = adr2->in(1);
+ const TypePtr* tp2 = adr2->bottom_type()->isa_ptr();
+ int load2_offset = tp2->offset();
+
+ LoadBNode *loadb3 = (LoadBNode *) in11;
+ Node *adr3 = loadb3->in(MemNode::Address);
+ Node *load3_base = adr3->in(1);
+ const TypePtr* tp3 = adr3->bottom_type()->isa_ptr();
+ int load3_offset = tp3->offset();
+
+ LoadBNode *loadb4 = (LoadBNode *) in5;
+ Node *adr4 = loadb4->in(MemNode::Address);
+ Node *load4_base = adr4->in(1);
+ const TypePtr* tp4 = adr4->bottom_type()->isa_ptr();
+ int load4_offset = tp4->offset();
+
+ if ( load1_base == load2_base &&
+ load1_base == load3_base &&
+ load1_base == load4_base &&
+ load1_offset + 1 == load2_offset &&
+ load2_offset + 1 == load3_offset &&
+ load3_offset + 1 == load4_offset ) {
+ return new (phase->C) LoadINode(NULL, load1_base, adr1, tp1, TypeInt::INT, MemNode::unordered);
+ }
+ }
+ }
+ }
+ }
+ }
+
return AddNode::Ideal(phase, can_reshape);
}
//------------------------------Identity---------------------------------------