< prev index next >

src/hotspot/share/opto/mulnode.cpp

Print this page
@@ -624,11 +624,11 @@
    [[maybe_unused]] Node* lo_proj = new ProjNode(umul_hi_lo, MulHiLoLNode::first_proj_num);
    [[maybe_unused]] Node* hi_proj = new ProjNode(umul_hi_lo, MulHiLoLNode::second_proj_num);
    return umul_hi_lo;
  }
  
- Node* MulHiLoLNode::match(const ProjNode* proj, const Matcher* match) {
+ Node* MulHiLoLNode::match(const ProjNode* proj, const Matcher* match, const RegMask*) {
    uint ideal_reg = proj->ideal_reg();
    RegMask rm;
    if (proj->_con == first_proj_num) {
      rm.assignFrom(match->firstL_proj_mask());
    } else {

@@ -866,10 +866,51 @@
          }
        }
      }
    }
  
+   // Search for GraphKit::mark_word_test patterns and fold the test if the result is statically known
+   Node* load1 = in(1);
+   Node* load2 = nullptr;
+   if (load1->is_Phi() && phase->type(load1)->isa_long()) {
+     load1 = in(1)->in(1);
+     load2 = in(1)->in(2);
+   }
+   if (load1 != nullptr && load1->is_Load() && phase->type(load1)->isa_long() &&
+       (load2 == nullptr || (load2->is_Load() && phase->type(load2)->isa_long()))) {
+     const TypePtr* adr_t1 = phase->type(load1->in(MemNode::Address))->isa_ptr();
+     const TypePtr* adr_t2 = (load2 != nullptr) ? phase->type(load2->in(MemNode::Address))->isa_ptr() : nullptr;
+     if (adr_t1 != nullptr && adr_t1->offset() == oopDesc::mark_offset_in_bytes() &&
+         (load2 == nullptr || (adr_t2 != nullptr && adr_t2->offset() == in_bytes(Klass::prototype_header_offset())))) {
+       if (mask == markWord::inline_type_pattern) {
+         if (adr_t1->is_inlinetypeptr()) {
+           set_req_X(1, in(2), phase);
+           return this;
+         } else if (!adr_t1->can_be_inline_type()) {
+           set_req_X(1, phase->longcon(0), phase);
+           return this;
+         }
+       } else if (mask == markWord::null_free_array_bit_in_place) {
+         if (adr_t1->is_null_free()) {
+           set_req_X(1, in(2), phase);
+           return this;
+         } else if (adr_t1->is_not_null_free()) {
+           set_req_X(1, phase->longcon(0), phase);
+           return this;
+         }
+       } else if (mask == markWord::flat_array_bit_in_place) {
+         if (adr_t1->is_flat()) {
+           set_req_X(1, in(2), phase);
+           return this;
+         } else if (adr_t1->is_not_flat()) {
+           set_req_X(1, phase->longcon(0), phase);
+           return this;
+         }
+       }
+     }
+   }
+ 
    return MulNode::Ideal(phase, can_reshape);
  }
  
  LShiftNode* LShiftNode::make(Node* in1, Node* in2, BasicType bt) {
    switch (bt) {
< prev index next >