src/share/vm/opto/matcher.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 7119644 Cdiff src/share/vm/opto/matcher.cpp

src/share/vm/opto/matcher.cpp

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 33,42 **** --- 33,43 ---- #include "opto/opcodes.hpp" #include "opto/regmask.hpp" #include "opto/rootnode.hpp" #include "opto/runtime.hpp" #include "opto/type.hpp" + #include "opto/vectornode.hpp" #include "runtime/atomic.hpp" #include "runtime/os.hpp" #ifdef TARGET_ARCH_MODEL_x86_32 # include "adfiles/ad_x86_32.hpp" #endif
*** 56,77 **** # include "adfiles/ad_ppc.hpp" #endif OptoReg::Name OptoReg::c_frame_pointer; - - - const int Matcher::base2reg[Type::lastype] = { - Node::NotAMachineReg,0,0, Op_RegI, Op_RegL, 0, Op_RegN, - Node::NotAMachineReg, Node::NotAMachineReg, /* tuple, array */ - Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, /* the pointers */ - 0, 0/*abio*/, - Op_RegP /* Return address */, 0, /* the memories */ - Op_RegF, Op_RegF, Op_RegF, Op_RegD, Op_RegD, Op_RegD, - 0 /*bottom*/ - }; - const RegMask *Matcher::idealreg2regmask[_last_machine_leaf]; RegMask Matcher::mreg2regmask[_last_Mach_Reg]; RegMask Matcher::STACK_ONLY_mask; RegMask Matcher::c_frame_ptr_mask; const uint Matcher::_begin_rematerialize = _BEGIN_REMATERIALIZE; --- 57,66 ----
*** 105,128 **** --- 94,129 ---- idealreg2spillmask [Op_RegN] = NULL; idealreg2spillmask [Op_RegL] = NULL; idealreg2spillmask [Op_RegF] = NULL; idealreg2spillmask [Op_RegD] = NULL; idealreg2spillmask [Op_RegP] = NULL; + idealreg2spillmask [Op_VecS] = NULL; + idealreg2spillmask [Op_VecD] = NULL; + idealreg2spillmask [Op_VecX] = NULL; + idealreg2spillmask [Op_VecY] = NULL; idealreg2debugmask [Op_RegI] = NULL; idealreg2debugmask [Op_RegN] = NULL; idealreg2debugmask [Op_RegL] = NULL; idealreg2debugmask [Op_RegF] = NULL; idealreg2debugmask [Op_RegD] = NULL; idealreg2debugmask [Op_RegP] = NULL; + idealreg2debugmask [Op_VecS] = NULL; + idealreg2debugmask [Op_VecD] = NULL; + idealreg2debugmask [Op_VecX] = NULL; + idealreg2debugmask [Op_VecY] = NULL; idealreg2mhdebugmask[Op_RegI] = NULL; idealreg2mhdebugmask[Op_RegN] = NULL; idealreg2mhdebugmask[Op_RegL] = NULL; idealreg2mhdebugmask[Op_RegF] = NULL; idealreg2mhdebugmask[Op_RegD] = NULL; idealreg2mhdebugmask[Op_RegP] = NULL; + idealreg2mhdebugmask[Op_VecS] = NULL; + idealreg2mhdebugmask[Op_VecD] = NULL; + idealreg2mhdebugmask[Op_VecX] = NULL; + idealreg2mhdebugmask[Op_VecY] = NULL; debug_only(_mem_node = NULL;) // Ideal memory node consumed by mach node } //------------------------------warp_incoming_stk_arg------------------------
*** 132,142 **** if( reg->is_stack() ) { // Stack slot argument? warped = OptoReg::add(_old_SP, reg->reg2stack() ); warped = OptoReg::add(warped, C->out_preserve_stack_slots()); if( warped >= _in_arg_limit ) _in_arg_limit = OptoReg::add(warped, 1); // Bump max stack slot seen ! if (!RegMask::can_represent(warped)) { // the compiler cannot represent this method's calling sequence C->record_method_not_compilable_all_tiers("unsupported incoming calling sequence"); return OptoReg::Bad; } return warped; --- 133,143 ---- if( reg->is_stack() ) { // Stack slot argument? warped = OptoReg::add(_old_SP, reg->reg2stack() ); warped = OptoReg::add(warped, C->out_preserve_stack_slots()); if( warped >= _in_arg_limit ) _in_arg_limit = OptoReg::add(warped, 1); // Bump max stack slot seen ! if (!RegMask::can_represent_arg(warped)) { // the compiler cannot represent this method's calling sequence C->record_method_not_compilable_all_tiers("unsupported incoming calling sequence"); return OptoReg::Bad; } return warped;
*** 300,310 **** // Compute highest outgoing stack argument as // _new_SP + out_preserve_stack_slots + max(outgoing argument size). _out_arg_limit = OptoReg::add(_new_SP, C->out_preserve_stack_slots()); assert( is_even(_out_arg_limit), "out_preserve must be even" ); ! if (!RegMask::can_represent(OptoReg::add(_out_arg_limit,-1))) { // the compiler cannot represent this method's calling sequence C->record_method_not_compilable("must be able to represent all call arguments in reg mask"); } if (C->failing()) return; // bailed out on incoming arg failure --- 301,311 ---- // Compute highest outgoing stack argument as // _new_SP + out_preserve_stack_slots + max(outgoing argument size). _out_arg_limit = OptoReg::add(_new_SP, C->out_preserve_stack_slots()); assert( is_even(_out_arg_limit), "out_preserve must be even" ); ! if (!RegMask::can_represent_arg(OptoReg::add(_out_arg_limit,-1))) { // the compiler cannot represent this method's calling sequence C->record_method_not_compilable("must be able to represent all call arguments in reg mask"); } if (C->failing()) return; // bailed out on incoming arg failure
*** 426,436 **** // Disallow any debug info in outgoing argument areas by setting the // initial mask accordingly. void Matcher::init_first_stack_mask() { // Allocate storage for spill masks as masks for the appropriate load type. ! RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask) * 3*6); idealreg2spillmask [Op_RegN] = &rms[0]; idealreg2spillmask [Op_RegI] = &rms[1]; idealreg2spillmask [Op_RegL] = &rms[2]; idealreg2spillmask [Op_RegF] = &rms[3]; --- 427,437 ---- // Disallow any debug info in outgoing argument areas by setting the // initial mask accordingly. void Matcher::init_first_stack_mask() { // Allocate storage for spill masks as masks for the appropriate load type. ! RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask) * (3*6+4)); idealreg2spillmask [Op_RegN] = &rms[0]; idealreg2spillmask [Op_RegI] = &rms[1]; idealreg2spillmask [Op_RegL] = &rms[2]; idealreg2spillmask [Op_RegF] = &rms[3];
*** 449,458 **** --- 450,464 ---- idealreg2mhdebugmask[Op_RegL] = &rms[14]; idealreg2mhdebugmask[Op_RegF] = &rms[15]; idealreg2mhdebugmask[Op_RegD] = &rms[16]; idealreg2mhdebugmask[Op_RegP] = &rms[17]; + idealreg2spillmask [Op_VecS] = &rms[18]; + idealreg2spillmask [Op_VecD] = &rms[19]; + idealreg2spillmask [Op_VecX] = &rms[20]; + idealreg2spillmask [Op_VecY] = &rms[21]; + OptoReg::Name i; // At first, start with the empty mask C->FIRST_STACK_mask().Clear();
*** 460,494 **** OptoReg::Name init = OptoReg::add(_old_SP, C->out_preserve_stack_slots()); for (i = init; i < _in_arg_limit; i = OptoReg::add(i,1)) C->FIRST_STACK_mask().Insert(i); // Add in all bits past the outgoing argument area ! guarantee(RegMask::can_represent(OptoReg::add(_out_arg_limit,-1)), "must be able to represent all call arguments in reg mask"); init = _out_arg_limit; for (i = init; RegMask::can_represent(i); i = OptoReg::add(i,1)) C->FIRST_STACK_mask().Insert(i); // Finally, set the "infinite stack" bit. C->FIRST_STACK_mask().set_AllStack(); // Make spill masks. Registers for their class, plus FIRST_STACK_mask. #ifdef _LP64 *idealreg2spillmask[Op_RegN] = *idealreg2regmask[Op_RegN]; idealreg2spillmask[Op_RegN]->OR(C->FIRST_STACK_mask()); #endif *idealreg2spillmask[Op_RegI] = *idealreg2regmask[Op_RegI]; idealreg2spillmask[Op_RegI]->OR(C->FIRST_STACK_mask()); *idealreg2spillmask[Op_RegL] = *idealreg2regmask[Op_RegL]; ! idealreg2spillmask[Op_RegL]->OR(C->FIRST_STACK_mask()); *idealreg2spillmask[Op_RegF] = *idealreg2regmask[Op_RegF]; idealreg2spillmask[Op_RegF]->OR(C->FIRST_STACK_mask()); *idealreg2spillmask[Op_RegD] = *idealreg2regmask[Op_RegD]; ! idealreg2spillmask[Op_RegD]->OR(C->FIRST_STACK_mask()); ! *idealreg2spillmask[Op_RegP] = *idealreg2regmask[Op_RegP]; ! idealreg2spillmask[Op_RegP]->OR(C->FIRST_STACK_mask()); if (UseFPUForSpilling) { // This mask logic assumes that the spill operations are // symmetric and that the registers involved are the same size. // On sparc for instance we may have to use 64 bit moves will // kill 2 registers when used with F0-F31. --- 466,527 ---- OptoReg::Name init = OptoReg::add(_old_SP, C->out_preserve_stack_slots()); for (i = init; i < _in_arg_limit; i = OptoReg::add(i,1)) C->FIRST_STACK_mask().Insert(i); // Add in all bits past the outgoing argument area ! guarantee(RegMask::can_represent_arg(OptoReg::add(_out_arg_limit,-1)), "must be able to represent all call arguments in reg mask"); init = _out_arg_limit; for (i = init; RegMask::can_represent(i); i = OptoReg::add(i,1)) C->FIRST_STACK_mask().Insert(i); // Finally, set the "infinite stack" bit. C->FIRST_STACK_mask().set_AllStack(); // Make spill masks. Registers for their class, plus FIRST_STACK_mask. + RegMask aligned_stack_mask = C->FIRST_STACK_mask(); + // Keep spill masks aligned. + aligned_stack_mask.clear_to_pairs(); + assert(aligned_stack_mask.is_AllStack(), "should be infinite stack"); + + *idealreg2spillmask[Op_RegP] = *idealreg2regmask[Op_RegP]; #ifdef _LP64 *idealreg2spillmask[Op_RegN] = *idealreg2regmask[Op_RegN]; idealreg2spillmask[Op_RegN]->OR(C->FIRST_STACK_mask()); + idealreg2spillmask[Op_RegP]->OR(aligned_stack_mask); + #else + idealreg2spillmask[Op_RegP]->OR(C->FIRST_STACK_mask()); #endif *idealreg2spillmask[Op_RegI] = *idealreg2regmask[Op_RegI]; idealreg2spillmask[Op_RegI]->OR(C->FIRST_STACK_mask()); *idealreg2spillmask[Op_RegL] = *idealreg2regmask[Op_RegL]; ! idealreg2spillmask[Op_RegL]->OR(aligned_stack_mask); *idealreg2spillmask[Op_RegF] = *idealreg2regmask[Op_RegF]; idealreg2spillmask[Op_RegF]->OR(C->FIRST_STACK_mask()); *idealreg2spillmask[Op_RegD] = *idealreg2regmask[Op_RegD]; ! idealreg2spillmask[Op_RegD]->OR(aligned_stack_mask); + if (Matcher::vector_size_supported(T_BYTE,4)) { + *idealreg2spillmask[Op_VecS] = *idealreg2regmask[Op_VecS]; + idealreg2spillmask[Op_VecS]->OR(C->FIRST_STACK_mask()); + } + if (Matcher::vector_size_supported(T_FLOAT,2)) { + *idealreg2spillmask[Op_VecD] = *idealreg2regmask[Op_VecD]; + idealreg2spillmask[Op_VecD]->OR(aligned_stack_mask); + } + if (Matcher::vector_size_supported(T_FLOAT,4)) { + aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecX); + assert(aligned_stack_mask.is_AllStack(), "should be infinite stack"); + *idealreg2spillmask[Op_VecX] = *idealreg2regmask[Op_VecX]; + idealreg2spillmask[Op_VecX]->OR(aligned_stack_mask); + } + if (Matcher::vector_size_supported(T_FLOAT,8)) { + aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecY); + assert(aligned_stack_mask.is_AllStack(), "should be infinite stack"); + *idealreg2spillmask[Op_VecY] = *idealreg2regmask[Op_VecY]; + idealreg2spillmask[Op_VecY]->OR(aligned_stack_mask); + } if (UseFPUForSpilling) { // This mask logic assumes that the spill operations are // symmetric and that the registers involved are the same size. // On sparc for instance we may have to use 64 bit moves will // kill 2 registers when used with F0-F31.
*** 805,814 **** --- 838,866 ---- idealreg2regmask[Op_RegI] = &spillI->out_RegMask(); idealreg2regmask[Op_RegL] = &spillL->out_RegMask(); idealreg2regmask[Op_RegF] = &spillF->out_RegMask(); idealreg2regmask[Op_RegD] = &spillD->out_RegMask(); idealreg2regmask[Op_RegP] = &spillP->out_RegMask(); + + // Vector regmasks. + if (Matcher::vector_size_supported(T_BYTE,4)) { + TypeVect::VECTS = TypeVect::make(T_BYTE, 4); + MachNode *spillVectS = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTS)); + idealreg2regmask[Op_VecS] = &spillVectS->out_RegMask(); + } + if (Matcher::vector_size_supported(T_FLOAT,2)) { + MachNode *spillVectD = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTD)); + idealreg2regmask[Op_VecD] = &spillVectD->out_RegMask(); + } + if (Matcher::vector_size_supported(T_FLOAT,4)) { + MachNode *spillVectX = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTX)); + idealreg2regmask[Op_VecX] = &spillVectX->out_RegMask(); + } + if (Matcher::vector_size_supported(T_FLOAT,8)) { + MachNode *spillVectY = match_tree(new (C, 3) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTY)); + idealreg2regmask[Op_VecY] = &spillVectY->out_RegMask(); + } } #ifdef ASSERT static void match_alias_type(Compile* C, Node* n, Node* m) { if (!VerifyAliases) return; // do not go looking for trouble by default
*** 1061,1071 **** // Keep track of the largest numbered stack slot used for an arg. // Largest used slot per call-site indicates the amount of stack // that is killed by the call. if( warped >= out_arg_limit_per_call ) out_arg_limit_per_call = OptoReg::add(warped,1); ! if (!RegMask::can_represent(warped)) { C->record_method_not_compilable_all_tiers("unsupported calling sequence"); return OptoReg::Bad; } return warped; } --- 1113,1123 ---- // Keep track of the largest numbered stack slot used for an arg. // Largest used slot per call-site indicates the amount of stack // that is killed by the call. if( warped >= out_arg_limit_per_call ) out_arg_limit_per_call = OptoReg::add(warped,1); ! if (!RegMask::can_represent_arg(warped)) { C->record_method_not_compilable_all_tiers("unsupported calling sequence"); return OptoReg::Bad; } return warped; }
*** 1249,1259 **** // Since the max-per-method covers the max-per-call-site and debug info // is excluded on the max-per-method basis, debug info cannot land in // this killed area. uint r_cnt = mcall->tf()->range()->cnt(); MachProjNode *proj = new (C, 1) MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj ); ! if (!RegMask::can_represent(OptoReg::Name(out_arg_limit_per_call-1))) { C->record_method_not_compilable_all_tiers("unsupported outgoing calling sequence"); } else { for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++) proj->_rout.Insert(OptoReg::Name(i)); } --- 1301,1311 ---- // Since the max-per-method covers the max-per-call-site and debug info // is excluded on the max-per-method basis, debug info cannot land in // this killed area. uint r_cnt = mcall->tf()->range()->cnt(); MachProjNode *proj = new (C, 1) MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj ); ! if (!RegMask::can_represent_arg(OptoReg::Name(out_arg_limit_per_call-1))) { C->record_method_not_compilable_all_tiers("unsupported outgoing calling sequence"); } else { for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++) proj->_rout.Insert(OptoReg::Name(i)); }
src/share/vm/opto/matcher.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File