--- old/src/share/vm/opto/addnode.cpp 2017-04-22 00:35:45.009662920 +0900 +++ new/src/share/vm/opto/addnode.cpp 2017-04-22 00:35:44.949661435 +0900 @@ -320,6 +320,81 @@ } } +// 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); }