comparison src/share/vm/opto/escape.cpp @ 7637:b30b3c2a0cf2

6896617: Optimize sun.nio.cs.ISO_8859_1$Encode.encodeArrayLoop() on x86 Summary: Use SSE4.2 and AVX2 instructions for encodeArray intrinsic. Reviewed-by: roland
author kvn
date Tue, 22 Jan 2013 15:34:16 -0800
parents 2aff40cb4703
children 6f3fd5150b67
comparison
equal deleted inserted replaced
7636:a7114d3d712e 7637:b30b3c2a0cf2
521 break; 521 break;
522 } 522 }
523 case Op_AryEq: 523 case Op_AryEq:
524 case Op_StrComp: 524 case Op_StrComp:
525 case Op_StrEquals: 525 case Op_StrEquals:
526 case Op_StrIndexOf: { 526 case Op_StrIndexOf:
527 case Op_EncodeISOArray: {
527 add_local_var(n, PointsToNode::ArgEscape); 528 add_local_var(n, PointsToNode::ArgEscape);
528 delayed_worklist->push(n); // Process it later. 529 delayed_worklist->push(n); // Process it later.
529 break; 530 break;
530 } 531 }
531 case Op_ThreadLocal: { 532 case Op_ThreadLocal: {
699 ELSE_FAIL("Op_StoreP"); 700 ELSE_FAIL("Op_StoreP");
700 } 701 }
701 case Op_AryEq: 702 case Op_AryEq:
702 case Op_StrComp: 703 case Op_StrComp:
703 case Op_StrEquals: 704 case Op_StrEquals:
704 case Op_StrIndexOf: { 705 case Op_StrIndexOf:
706 case Op_EncodeISOArray: {
705 // char[] arrays passed to string intrinsic do not escape but 707 // char[] arrays passed to string intrinsic do not escape but
706 // they are not scalar replaceable. Adjust escape state for them. 708 // they are not scalar replaceable. Adjust escape state for them.
707 // Start from in(2) edge since in(1) is memory edge. 709 // Start from in(2) edge since in(1) is memory edge.
708 for (uint i = 2; i < n->req(); i++) { 710 for (uint i = 2; i < n->req(); i++) {
709 Node* adr = n->in(i); 711 Node* adr = n->in(i);
2579 // we are looking for. 2581 // we are looking for.
2580 break; 2582 break;
2581 } 2583 }
2582 // Otherwise skip it (the call updated 'result' value). 2584 // Otherwise skip it (the call updated 'result' value).
2583 } else if (result->Opcode() == Op_SCMemProj) { 2585 } else if (result->Opcode() == Op_SCMemProj) {
2584 assert(result->in(0)->is_LoadStore(), "sanity"); 2586 Node* mem = result->in(0);
2585 const Type *at = igvn->type(result->in(0)->in(MemNode::Address)); 2587 Node* adr = NULL;
2588 if (mem->is_LoadStore()) {
2589 adr = mem->in(MemNode::Address);
2590 } else {
2591 assert(mem->Opcode() == Op_EncodeISOArray, "sanity");
2592 adr = mem->in(3); // Memory edge corresponds to destination array
2593 }
2594 const Type *at = igvn->type(adr);
2586 if (at != Type::TOP) { 2595 if (at != Type::TOP) {
2587 assert (at->isa_ptr() != NULL, "pointer type required."); 2596 assert (at->isa_ptr() != NULL, "pointer type required.");
2588 int idx = C->get_alias_index(at->is_ptr()); 2597 int idx = C->get_alias_index(at->is_ptr());
2589 assert(idx != alias_idx, "Object is not scalar replaceable if a LoadStore node access its field"); 2598 assert(idx != alias_idx, "Object is not scalar replaceable if a LoadStore node access its field");
2590 break; 2599 break;
2591 } 2600 }
2592 result = result->in(0)->in(MemNode::Memory); 2601 result = mem->in(MemNode::Memory);
2593 } 2602 }
2594 } 2603 }
2595 if (result->is_Phi()) { 2604 if (result->is_Phi()) {
2596 PhiNode *mphi = result->as_Phi(); 2605 PhiNode *mphi = result->as_Phi();
2597 assert(mphi->bottom_type() == Type::MEMORY, "memory phi required"); 2606 assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
2925 // (through CheckCastPP nodes) even for debug info. 2934 // (through CheckCastPP nodes) even for debug info.
2926 Node* m = use->in(TypeFunc::Memory); 2935 Node* m = use->in(TypeFunc::Memory);
2927 if (m->is_MergeMem()) { 2936 if (m->is_MergeMem()) {
2928 assert(_mergemem_worklist.contains(m->as_MergeMem()), "EA: missing MergeMem node in the worklist"); 2937 assert(_mergemem_worklist.contains(m->as_MergeMem()), "EA: missing MergeMem node in the worklist");
2929 } 2938 }
2939 } else if (use->Opcode() == Op_EncodeISOArray) {
2940 if (use->in(MemNode::Memory) == n || use->in(3) == n) {
2941 // EncodeISOArray overwrites destination array
2942 memnode_worklist.append_if_missing(use);
2943 }
2930 } else { 2944 } else {
2931 uint op = use->Opcode(); 2945 uint op = use->Opcode();
2932 if (!(op == Op_CmpP || op == Op_Conv2B || 2946 if (!(op == Op_CmpP || op == Op_Conv2B ||
2933 op == Op_CastP2X || op == Op_StoreCM || 2947 op == Op_CastP2X || op == Op_StoreCM ||
2934 op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || 2948 op == Op_FastLock || op == Op_AryEq || op == Op_StrComp ||
2960 } else if (n->is_MemBar()) { // Initialize, MemBar nodes 2974 } else if (n->is_MemBar()) { // Initialize, MemBar nodes
2961 // we don't need to do anything, but the users must be pushed 2975 // we don't need to do anything, but the users must be pushed
2962 n = n->as_MemBar()->proj_out(TypeFunc::Memory); 2976 n = n->as_MemBar()->proj_out(TypeFunc::Memory);
2963 if (n == NULL) 2977 if (n == NULL)
2964 continue; 2978 continue;
2979 } else if (n->Opcode() == Op_EncodeISOArray) {
2980 // get the memory projection
2981 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
2982 Node *use = n->fast_out(i);
2983 if (use->Opcode() == Op_SCMemProj) {
2984 n = use;
2985 break;
2986 }
2987 }
2988 assert(n->Opcode() == Op_SCMemProj, "memory projection required");
2965 } else { 2989 } else {
2966 assert(n->is_Mem(), "memory node required."); 2990 assert(n->is_Mem(), "memory node required.");
2967 Node *addr = n->in(MemNode::Address); 2991 Node *addr = n->in(MemNode::Address);
2968 const Type *addr_t = igvn->type(addr); 2992 const Type *addr_t = igvn->type(addr);
2969 if (addr_t == Type::TOP) 2993 if (addr_t == Type::TOP)
2997 // push user on appropriate worklist 3021 // push user on appropriate worklist
2998 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { 3022 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
2999 Node *use = n->fast_out(i); 3023 Node *use = n->fast_out(i);
3000 if (use->is_Phi() || use->is_ClearArray()) { 3024 if (use->is_Phi() || use->is_ClearArray()) {
3001 memnode_worklist.append_if_missing(use); 3025 memnode_worklist.append_if_missing(use);
3002 } else if(use->is_Mem() && use->in(MemNode::Memory) == n) { 3026 } else if (use->is_Mem() && use->in(MemNode::Memory) == n) {
3003 if (use->Opcode() == Op_StoreCM) // Ignore cardmark stores 3027 if (use->Opcode() == Op_StoreCM) // Ignore cardmark stores
3004 continue; 3028 continue;
3005 memnode_worklist.append_if_missing(use); 3029 memnode_worklist.append_if_missing(use);
3006 } else if (use->is_MemBar()) { 3030 } else if (use->is_MemBar()) {
3007 memnode_worklist.append_if_missing(use); 3031 memnode_worklist.append_if_missing(use);
3008 #ifdef ASSERT 3032 #ifdef ASSERT
3009 } else if(use->is_Mem()) { 3033 } else if(use->is_Mem()) {
3010 assert(use->in(MemNode::Memory) != n, "EA: missing memory path"); 3034 assert(use->in(MemNode::Memory) != n, "EA: missing memory path");
3011 } else if (use->is_MergeMem()) { 3035 } else if (use->is_MergeMem()) {
3012 assert(_mergemem_worklist.contains(use->as_MergeMem()), "EA: missing MergeMem node in the worklist"); 3036 assert(_mergemem_worklist.contains(use->as_MergeMem()), "EA: missing MergeMem node in the worklist");
3037 } else if (use->Opcode() == Op_EncodeISOArray) {
3038 if (use->in(MemNode::Memory) == n || use->in(3) == n) {
3039 // EncodeISOArray overwrites destination array
3040 memnode_worklist.append_if_missing(use);
3041 }
3013 } else { 3042 } else {
3014 uint op = use->Opcode(); 3043 uint op = use->Opcode();
3015 if (!(op == Op_StoreCM || 3044 if (!(op == Op_StoreCM ||
3016 (op == Op_CallLeaf && use->as_CallLeaf()->_name != NULL && 3045 (op == Op_CallLeaf && use->as_CallLeaf()->_name != NULL &&
3017 strcmp(use->as_CallLeaf()->_name, "g1_wb_pre") == 0) || 3046 strcmp(use->as_CallLeaf()->_name, "g1_wb_pre") == 0) ||